Adding Table of Contents (TOC) to Next.js Markdown blog

By Priyash Patil | Updated: Oct 21, 2023 12PM IST

This is the follow-up to my previous post about adding categories support. To follow with this post you can check out the source code from this GitHub Revision.

Problem Statement

Just converting Markdown to HTML is not enough. We could add the table of content manually but for every change, it would require manual updates each time and possibly can break old links if not maintained correctly.

Solution

As you can see in to that I'm already using rmark-html to convert Markdown to HTML. remark-html is package from unified.js. Similar to remark-html, unified.js also have other packages the ecosystem. So for our case we will be using remark-toc.

Install unified.js packages

Install new packages:

npm install rehype-format rehype-sanitize rehype-slug rehype-stringify remark-parse remark-rehype remark-toc unified

Uninstall unnecessary packages:

npm uninstall remark remark-html

Refactoring getPostData

import remarkToc from "remark-toc";
import rehypeSlug from "rehype-slug";
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeStringify from "rehype-stringify";
import rehypeSanitize from "rehype-sanitize";
import rehypeFormat from "rehype-format";

const processedContent = await unified()
  .use(remarkParse)
  .use(remarkToc, { tight: true, ordered: true })
  .use(remarkRehype)
  .use(rehypeSanitize)
  .use(rehypeSlug)
  .use(rehypeFormat)
  .use(rehypeStringify)
  .process("fileContents");

Source code

The final source code is on this GitHub Revision. Do note that this source repository is not my actual website. I'll be maintaining a separate source code repository for this blog series.

Conclusion

While making changes referring from docs learned that It did not work at first. Later found that the markdown file must have table of contents heading specified in file. Also, ToC package does not add ID's to headings. Had to remove remark and remark-html and use unified to use multiple package ecosystem.

The ToC works add expected. Also, found that unified.js has excellent plugins which can be used to add more features. So, stay tuned for that.