UNPKG

@wisp-cms/table-of-content

Version:

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.

127 lines (93 loc) 5.48 kB
# HTML to TOC Converter 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. ## Motivation 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](https://www.wisp.blog/?utm_source=npm&utm_medium=web&utm_campaign=toc-readme), a headless CMS tailored for Next.js. ## Installation ```bash npm install @wisp-cms/table-of-content ``` ## Usage ### Code Example Enhance your posts with a dynamic TOC using the `generateTableOfContents` function. ```tsx 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. ```tsx 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> ); } ``` ## How It Works 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. ![How It Works](how-it-works.png) 1. **Raw HTML Input**: Your initial HTML content, typically fetched from a headless CMS like Wisp CMS. 2. **generateTableOfContents Function**: This function parses the HTML, identifies headings, generates unique IDs for them, and creates a structured TOC array. 3. **Modified HTML Output**: The original HTML with added IDs for each heading. 4. **TOC Array Output**: An array of `TableOfContentsItem` objects, each containing information about a heading's ID, text, and level. 5. **Render Modified HTML**: Use the modified HTML to render your main content. 6. **Render TOC Component**: Use the TOC array to render a navigable TOC component on your page. ## Configuration ### HeaderConfig Interface You can selectively enable or disable heading levels for the TOC generation. ```ts { 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 } ``` ### TableOfContentsItem Interface 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. ```ts 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.) } ``` ## About Wisp CMS ### Content Updates Slowing You Down? - **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. ### Solution **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](https://www.wisp.blog/?utm_source=npm&utm_medium=web&utm_campaign=toc-readme).