2021-06-17
記事の目次を表示するようにした
再び、このGatsby製ブログの機能改善について。
記事の見出しから目次を生成し、記事ページの上部(タイトルの直下)に表示するようにした。
目次の生成方法について調査
記事の見出しにアンカーリンクがつくようにした でもそうだったように、gatsbyプラグインを使って目次の生成ができるようなので最初はプラグインについて調べていた。
しかし、gatsby-transformer-remark を入れている時点で GraphQL を使って tableOfContents
という属性が取れる事に気がついた。
実際にローカルホストで GraphiQL を使って確認してみると、記事の見出しから目次をHTMLで取得できることを確認できた。
目次用コンポーネントを作る
ここまでくれば、あとはコンポーネントに切り出してスタイルを当てるだけで十分そうだなと考え、次のような Toc
コンポーネントを新規作成。
// src/components/toc.js
const Toc = ({ tableOfContents }) => {
return (
<div
className={`bg-gray-50 pt-4 pb-2 px-4 rounded text-sm`}
>
<span className={`block font-semibold`}>
目次
</span>
<div
dangerouslySetInnerHTML={{ __html: tableOfContents }}
>
</div>
</div>
)
}
export default Toc
あとはこれを記事詳細のコンポーネントから呼び出せば良いだけとなる。
見出しが存在しない場合は目次コンポーネントをレンダリングしない
目次を表示するときに1点気をつけたことは、見出しが1つも存在しない記事を考慮すること。 見出しが1つも無いと謎のグレーの枠だけが表示されてしまうため、そういった場合はそもそもコンポーネントをレンダリングしないようにする。
ReactやJSXには全然明るくないのだが、調べたところ次のようにすると簡潔に書けるようだったのでそのようにした。
const { markdownRemark } = data
const { frontmatter, html, tableOfContents } = markdownRemark
return (
<Layout>
// ...
{tableOfContents && <Toc tableOfContents={tableOfContents} />}
// ...
</Layout>
)
以上。徐々にブログの機能が増えて楽しくなってきた。
<< 前の記事記事の見出しにアンカーリンクがつくようにした
次の記事 >>はてなブログからGatsby製ブログに完全移行した