アイキャッチアイコン

GatsbyJSで目次を作成する

2021-06-26

やりたいこと

Markdown形式で書いたブログ記事の中に目次を追加し、各ヘッダーへのジャンプができるようにする。

やったこと

以下の2つのプラグインを利用する。

Markdown形式で記事を作成している場合、gatsby-transformer-remark については既に導入済みのはず。このプラグインを利用して、まずは目次を表示する。

gatsby-starter-blogを使っている場合、記事情報は data という名前の propsとして受け取る形になっている。

この data オブジェクトの中に、GraphQLで目次を利用するための tableOfContents が存在する。 これをGraphQLに追記し、return 部分に dangerouslySetInnerHTML={{ __html: post.tableOfContents }} を追記する。


const BlogPostTemplate = ({ data, location }) => {

  return (
    // 目次を表示させたい箇所に以下を追記する
    <div dangerouslySetInnerHTML={{ __html: post.tableOfContents }} />
  )
}

export default BlogPostTemplate

export const pageQuery = graphql`
  query BlogPostBySlug(
    $id: String!
    $previousPostId: String
    $nextPostId: String
  ) {
    markdownRemark(id: { eq: $id }) {
      id
      excerpt(pruneLength: 160)
      html

      // 以下追記
      tableOfContents(
        absolute: false
        pathToSlugField: "frontmatter.path"
        maxDepth: 3
      )

    }
  }
`

ここまでの状態で、目次がリスト形式で出力されるようになる。

CSSを調整したい場合は、 <div dangerouslySetInnerHTML={{ __html: post.tableOfContents }} /> に対して className を指定するとよい。

ただ、このままでは各ヘッダーに対して id が設定されていないため、目次をクリックしてもスクロールが発生しない。これを解決するために、 gatsby-remark-autolink-headers をインストールする。

インストール後、 gatsby-config.js に設定を行う。

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

オプションについて

今回指定したオプションは以下の2種類。

icon : false デフォルトではヘッダーにハイパーリンクのアイコン(🔗 ←これ)が挿入されてしまう。表示させたくなかったため false を指定。

maintainCase : false ヘッダーに挿入されるidについて、大文字小文字の保持するかの設定。一見、保持したほうが良さそうに思えるが、目次側の href属性に小文字が設定されているため大文字を保持してしまうとジャンプが効かなくなる。false を指定すると小文字で揃えることができたため、そうしている。

その他オプションについては、Document を参照。

注意点

gatsby-remark-autolink-headersgatsby-config.js に記述する際、gatsby-remark-prismjs よりも前に記述する必要がある。
Document にも以下の記述がある。

Note: if you are using gatsby-remark-prismjs, make sure that it’s listed after this plugin. Otherwise, you might face an issue described here: https://github.com/gatsbyjs/gatsby/issues/5764.


プロフィールアイコン

yoshiba

医療機関向けシステムのエンジニアをしています。 フロントエンドが好きで、最近はJamstackに夢中です。

© 2022, yoshiba All rights reserved.