Gatsby.js ブログへの目次追加
どうも、うしじです。
Gatsby.js + Netlifyへブログを移行してから、少しずつカスタマイズを進めています。まずは、ブログに目次を追加したので、その方法について記載したいと思います。
利用したGatsbyプラグイン
本ブログは、Markdownで記載しています。Markdownから自動で目次を作成するために、今回は下記の2つのプラグインを用いました。
Markdownから目次の抽出
目次を自動で抽出するには、gatsby-transformer-remarkを用います。
本ブログでは、既にgatsby-transformer-remarkを利用しているので、そのまま用います。
下記のように、blogTemplate.js
を更新します。これだけで、自動でブログの各ページに目次を挿入することができます。更新のポイントは下記の2点。
- graphql に tableOfContents の記述を追加
- ブログコンテンツの前に
dangerouslySetInnerHTML={{ __html: tableOfContents }}
の記述を追加
import React from "react"
import Helmet from 'react-helmet';
import { graphql } from "gatsby"
import Layout from "../components/layout"
export default function Template({
data,
}) {
const { site, markdownRemark } = data
const { siteMetadata } = site
const { frontmatter, tableOfContents ,html } = markdownRemark
return (
<Layout>
<Helmet>
<title>{frontmatter.title} | {siteMetadata.title}</title>
<meta name="description" content={frontmatter.metaDescription} />
</Helmet>
<div className="blog-post-container">
<article className="post">
{!frontmatter.thumbnail && (
<div className="post-thumbnail">
<h1 className="post-title">{frontmatter.title}</h1>
<div className="post-meta">{frontmatter.date}</div>
</div>
)}
{!!frontmatter.thumbnail && (
<div className="post-thumbnail" style={{backgroundImage: `url(${frontmatter.thumbnail})`}}>
<h1 className="post-title">{frontmatter.title}</h1>
<div className="post-meta">{frontmatter.date}</div>
</div>
)}
<div
className="table-of-content"
dangerouslySetInnerHTML={{ __html: tableOfContents }}
/>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</article>
</div>
</Layout>
)
}
export const pageQuery = graphql`
query($path: String!) {
site {
siteMetadata {
title
}
}
markdownRemark(frontmatter: { path: { eq: $path } }) {
html
tableOfContents(
absolute: false
pathToSlugField: "frontmatter.path"
maxDepth: 3
)
frontmatter {
date(formatString: "MMMM DD, YYYY")
path
title
thumbnail
metaDescription
}
}
}
`
目次のスタイルシート更新
上記の対応だけだと、htmlのリストそのままで出力されるので、global.scss を更新します。 今回は、下記のようなスタイルシートにしました。
.table-of-content {
max-width: 600px;
margin: 2rem auto;
border: solid #dadada 1px;
border-radius: 8px;
box-shadow :0px 0px 5px silver;
padding: 0.5rem 0.5rem 0.5rem 2rem;
line-height: 1.5;
&:before {
content: "目次";
font-size: 110%;
font-weight: bold;
}
}
見出しにID挿入
最後に、Markdownの見出しに、自動でIDを挿入するようにします。これによって、目次の各見出しをクリックした際に、その目次へ移動できるようにします。
ID挿入には、gatsby-remark-autolink-headersを用います。
gatsby-remark-autolink-headersをインストールし、下記のように、gatsby-config.jsに追加するだけで、IDを自動で挿入できます。
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-autolink-headers`,
options: {
offsetY: `30`,
icon: false,
className: `remark-autolink-headers`,
maintainCase: false,
},
},
{
resolve: `gatsby-remark-prismjs`,
options: {
classPrefix: "language-",
inlineCodeMarker: null,
aliases: {},
showLineNumbers: false,
noInlineHighlight: false,
},
}],
},
},
これで目次の完成です!