A flexible, headless solution to generate a Table of Contents (TOC) from HTML. Perfect for server-side frameworks like Next.js, Vite, Remix, and more. Easily integrate within your existing components and styling.
This package builds a table of contents (TOC) from headings in an HTML document. It is particularly useful for documentation websites or long content pages as it makes navigation easier. This package enables developers to effortlessly generate a TOC on both node.js and browser environment, offering an improved user experience without causing hydration errors in SSR-enabled environments.
The package is created by Wisp CMS, a headless CMS tailored for Next.js.
npm install @wisp-cms/table-of-content
Enhance your posts with a dynamic TOC using the generateTableOfContents
function.
import React from "react";
import { generateTableOfContents } from "@wisp-cms/table-of-content";
export function PostContentWithTOC({ content }: { content: string }) {
const { modifiedHtml, tableOfContents } = generateTableOfContents(content);
return (
<div className="flex">
<div className="prose w-full">
<div
className="blog-content"
dangerouslySetInnerHTML={{ __html: modifiedHtml }}
/>
</div>
<div className="w-1/4">
<div className="sticky top-0 max-h-screen overflow-y-auto">
<div className="text-lg font-semibold">Table of Contents</div>
<TableOfContents items={tableOfContents} />
</div>
</div>
</div>
);
}
Using TableOfContentsItem, you can map through the items to create your TOC.
import React from "react";
import { TableOfContentsItem } from "@wisp-cms/table-of-content";
function TableOfContents({ items }: { items: TableOfContentsItem[] }) {
return (
<ul>
{items.map((item) => (
<li key={item.id} style={{ marginLeft: `${item.level - 1}em` }}>
<a href={`#${item.id}`}>{item.text}</a>
</li>
))}
</ul>
);
}
The generateTableOfContents
function processes your raw HTML and generates a structured output that includes the modified HTML with added IDs for each heading and an array of TOC items. This makes it easy to integrate into your existing components and styling.
- Raw HTML Input: Your initial HTML content, typically fetched from a headless CMS like Wisp CMS.
- generateTableOfContents Function: This function parses the HTML, identifies headings, generates unique IDs for them, and creates a structured TOC array.
- Modified HTML Output: The original HTML with added IDs for each heading.
-
TOC Array Output: An array of
TableOfContentsItem
objects, each containing information about a heading's ID, text, and level. - Render Modified HTML: Use the modified HTML to render your main content.
- Render TOC Component: Use the TOC array to render a navigable TOC component on your page.
You can selectively enable or disable heading levels for the TOC generation.
{
h1: true, // Parses <h1> headings
h2: true, // Parses <h2> headings
h3: true, // Parses <h3> headings
h4: true, // Parses <h4> headings
h5: true, // Parses <h5> headings
h6: true, // Parses <h6> headings
}
The generateTableOfContents
function returns an array of TableOfContentsItem
objects. Each item in the array represents a heading in the HTML, making it simple to render your TOC.
export interface TableOfContentsItem {
id: string; // Unique identifier for the heading
text: string; // The text within the heading tag
level: number; // The level of the heading (e.g., 1 for <h1>, 2 for <h2>, etc.)
}
- Interruption from Non-Developers: Constantly being pulled away to help with blog updates and formatting? Don't let these interruptions distract you from critical features.
- Image Hosting Frustrations: Struggling to upload and serve images without cluttering your codebase? Managing images can be a real hassle.
- Distracted from Core Features: Spending too much time on pagination, related articles, and search? Don't let these distract you from shipping features that move the needle.
Ship Content & Features Faster!
- Effortless Integration with Next.js: Integrate Wisp into your Next.js site using our SDK. Only a few lines of code are needed, complete with TypeScript types. Save precious development time for more critical tasks.
- Lightning-Fast Content Delivery: Your content and images are served via a global CDN, ensuring blazing fast rendering and superior SEO. Leverage Next.js caching to serve content instantaneously for users worldwide.
- Distraction-Free Editor: Our editor requires no markdown skills. Designed to feel like Medium or Notion, it provides a familiar, user-friendly interface. Your team can manage formatting on their own, even embedding YouTube videos effortlessly.
Learn more about boosting organic traffic and efficient content management with Wisp's built-in SEO features at Wisp CMS.