Gatsby.jsのMarkdown記事に目次を生成する

image.png (34.9 kB)

TOC

今回はGatsby.jsのブログ記事に、目次を生成する手順をまとめていきたいと思います。

目次というのは、記事の見出しがリスト形式で表示されていて、クリックすると該当の章へ移動するといったものになります。

Gatsby.jsではプラグインを使うことで比較的簡単に実装する事ができます。

前提

はじめに

目次の実装には、大きく分けて3つの手順があります。

  1. 見出し(hタグ)にページ内リンク用のidを付与する
  2. 見出し(hタグ)のテキストを取得する
  3. <a>タグのhref属性に見出し(hタグ)のid設定する

こちらの処理を実装する事ができれば、目次の完成です。

見出しにidを付与する

記事の見出し(hタグ)にidを付与してくれるgatsby-remark-autolink-headersというプラグインが公開されているので、こちらの導入から行います。

まずはgatsby-remark-autolink-headersプラグインをインストールします。

terminal
$ npm install gatsby-remark-autolink-headers
または
$ yarn add gatsby-remark-autolink-headers

インスールが完了したら、gatsby-transformer-remarkのオプションにインストールしたプラグインを追加します。

gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [`gatsby-remark-autolink-headers`],
      },
    },
  ],
}

このプラグインを適用するだけで、ブログ記事内の見出しにidが付与され、リンクを示すアイコンも生成されます。

image.png (17.0 kB)

オプション

gatsby-remark-autolink-headersはいくつかのオプションを設定する事ができます。 詳細はリンク先を参照していただきたいのですが、ここでは特に目次の実装に役立ちそうなものを取り上げたいと思います。

  • icon(Template literal or Boolean):独自のSVGアイコンを設定、またはアイコンを非表示
  • className(String):アンカーアイコンに独自クラスを設定
  • elements(Array):idやアンカーアイコンを設定するhタグを指定
gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-autolink-headers`,
            options: {
              className: `toc-icon`,
              elements: [`h2`],
            },
          },
        ],
      },
    },
  ],
}

注意点1

プロジェクトにgatsby-remark-prismjsを導入している場合は、必ず gatsby-transformer-remarkgatsby-remark-prismjs前にくるよう設定をしてください。

gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          `gatsby-remark-autolink-headers`,
          {
            resolve: `gatsby-remark-prismjs`,
            options: {
              //
              //
              //
            },
          },
        ],
      },
    },
  ]
}

注意点2

2020年11月現在、Gatsby.jsでは内部ハッシュリンクがうまく機能しないという問題があるそうです。

https://github.com/gatsbyjs/gatsby/issues/25778

恒久対応として、ハッシュリンクを設定するページURLをカスタマイズし、末尾に/を設定する事で、一時的にこの問題を回避する事ができます。

[NG]
https://domain/post/anchor-link#title1
[OK]
https://domain/post/anchor-link/#title1

または、issueでのやりとりでもあるように、Gatsby.js内部で使用されているgatsby-react-router-scrollの一部を、patch-packageを使って修正する事で正常に動作するようです。 ですが、その修正に伴う影響範囲は調べていないので、こちらを適用する際は自己責任でお願いいたします。

Markdown記事の中に目次を作成する

次は目次要素の生成を行います。

gatsby-remark-table-of-contentsは、Markdown記事内に特定のコードブロックを記述する事で、そのコードブロックを目次に変換してれるプラグインです。

まずはプラグインをインストールします。

terminal
$ npm install gatsby-remark-table-of-contents
または
$ yarn add gatsby-remark-table-of-contents

プラグインをプロジェクトに適用します。

gatsby-config.js
module.exports =  {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          `gatsby-remark-table-of-contents`,
          `gatsby-remark-autolink-headers`,
        ],
      },
    },
  ],
}

適用後は、下記コードブロックをMarkdown記事内に挿入するだけで目次が生成されます。 # This code block gets replaced with the TOCは削除しても構いません。

```toc
# This code block gets replaced with the TOC
```

オプション

こちらもgatsby-remark-autolink-headersと同樣にオプションが指定できます。

  • exclude(String or Array):指定した文字列に一致するタイトルを目次から除外
  • fromHeading(Number):目次を生成する最小のhタグ(デフォルトは<h2>
  • toHeading(Number):目次を生成する最大のhタグ(デフォルトは<h6>
  • className(String):生成された目次要素のクラス名を設定(デフォルトはtoc
gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-table-of-contents`,
            options: {
              exclude: ["Table of Contents", "TOC", "目次"],
              fromHeading: 2,
              toHeading: 5,
              className: "toc-block"
            },
          },
          `gatsby-remark-autolink-headers`,
        ],
      },
    },
  ]
}

コードブロック内に上記のオプションを指定する事で、記事毎に目次のオプションを指定する事もできます。

```toc
# This code block gets replaced with the TOC
exclude: Table of Contents
tight: false,
from-heading: 2
to-heading: 6
class-name: "table-of-contents"
```

まとめ

今回取り上げたプラグインを導入する事で、コードを変更する事なく、簡単に目次を導入する事ができます。

また、Markdownの記事内のコードブロックを目次に変換する為、目次を表示したく無い場合にも簡単に対応する事ができます。

Gatsby.js製のブログをお持ちの方で、お手軽に目次を導入してみたい方は、是非この2つのプラグインを検討してみてはいかがでしょうか?

CONTACT
© 2023, Kakkiii All Rights Reserved.