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

By Priyash Patil | 2 min read | Updated: Feb 14, 2022 10AM UTC

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.

Keep the Conversation Going

I hope you found this post helpful! If you have any questions or feedback, feel free to reach out. You can also find me on X (Twitter) @priyashpatil for additional insights and updates on my latest content.

Related

Featured on laravel-news.com and benjamincrozat.com.

Optimized image uploads with CKEditor and Laravel

By Priyash Patil on Friday, 03 November 2023

Bootstrap 5 Remove Unused CSS with Vite and PurgeCSS

By Priyash Patil on Wednesday, 17 January 2024

Laravel Vite Deploy Assets to Global CDN

By Priyash Patil on Friday, 19 January 2024

Laravel file upload with validation example

By Priyash Patil on Thursday, 25 January 2024