Skip to content

SSGを適用したNextjsで目次を生成する

2020/12/29

TypeScript

目次

目次

  1. はじめに
  2. Nextjs で SSG を適用する
    1. 目次を生成する

はじめに

SSG を適用した Next.js で,目次(Table of Content)を生成する方法を紹介します。

h2 タグを大目次,h3 タグを小目次とし,こちらのような目次を生成できます。

toc-result

こちらのブログは Next.js で作成しており,目次を生成しています。具体的なコードを見たい方は,こちらのリポジトリを参考にしてください。

https://github.com/kawa1214/micro-cms-nextjs-blog-boiler-template

Nextjs で SSG を適用する

Next.js では getStaticProps を用いることで,静的なファイルを事前に生成できます。

./pages/blogs/[id].tsx

export const getStaticProps: GetStaticProps = async context => {
  const id = context.params.id;
  const key = {
    headers: { "X-API-KEY": process.env.API_KEY },
  };

  const res = await fetch(process.env.ENDPOINT + "/blogs/" + id, key);
  const blog: BlogType = await res.json();

  return {
    props: {
      blog: blog,
    },
  };
};

目次を生成する

cheerio で html を解析し,目次を生成します。

今回は,h2 を大目次,h3 を小目次としています。

./pages/blogs/[id].tsx

const Blog: React.FC<BlogProps> = ({ blog, toc }) => {
  return (
    <>
      <div
        id="blog_toc"
        dangerouslySetInnerHTML={{
          __html: toc,
        }}
      />
    </>
  );
};
export default Blog;

const generateTableOfContent = (body: string) => {
  const $ = cheerio.load(body, { decodeEntities: false });
  let generateHtml = "";
  generateHtml = generateHtml + "<ul>";
  $("h2, h3").each((index, elm) => {
    const text = $(elm).html();
    const tag = $(elm)[0].name;

    const refId = $(elm)[0].attribs.id;
    generateHtml =
      generateHtml +
      `<li class="toc_${tag}" key=${index}>` +
      `  <a href="#${refId}">${text}</a>` +
      "</li>";
  });
  generateHtml = generateHtml + "</ul>";
  return generateHtml;
};

export const getStaticProps: GetStaticProps = async context => {
  const id = context.params.id;
  const key = {
    headers: { "X-API-KEY": process.env.API_KEY },
  };

  const res = await fetch(process.env.ENDPOINT + "/blogs/" + id, key);
  const blog: BlogType = await res.json();
  const toc: string = generateTableOfContent(blog.body);

  return {
    props: {
      blog: blog,
      toc: toc,
    },
  };
};

生成した HTML に CSS を適用します。こちらのサンプルコードは tailwind css を使用しています。

./styles/Blog.module.css

/* blog table of content*/
#blog_toc ul {
  @apply bg-white rounded px-2 py-2;
}

#blog_toc li {
  @apply my-1.5 ml-4;
}

#blog_toc a:link {
  @apply text-gray-900;
}

#blog_toc a:visited {
  @apply text-gray-900;
}

#blog_toc a:hover {
  color: #4c74b9;
}

#blog_toc a:active {
  color: #4c74b9;
}

#blog_toc .toc_h3 {
  @apply pl-4;
}