Add table of contents to MDX.
npm i --save next-mdx-toc remark-slug remark-autolink-headings
- Retrieve the MDX node using
getMdxNode
:
const doc = await getMdxNode("doc", context, {
mdxOptions: {
remarkPlugins: [
require("remark-slug"),
require("remark-autolink-headings"),
],
},
})
- Then call
getTableOfContents(node: MdxNode): TableOfContents
:
const toc = await getTableOfContents(doc)
import * as React from "react"
import { getMdxNode } from "next-mdx/server"
import { getTableOfContents } from "next-mdx-toc"
export default function Page({ doc, tableOfContents }) {}
export async function getStaticProps(context) {
const doc = await getMdxNode("doc", context, {
mdxOptions: {
remarkPlugins: [
require("remark-slug"),
require("remark-autolink-headings"),
],
},
})
return {
props: {
doc,
tableOfContents: await getTableOfContents(doc),
},
}
}
To render the table of contents, use a recursive component type:
import { TableOfContents } from "next-mdx-toc"
function Toc({ tree }: { tree: TableOfContents }) {
return tree?.items.length ? (
<ul>
{tree.items.map((item) => {
return (
<li key={item.title}>
<a href={item.url}>{item.title}</a>
{item.items?.length ? <Toc tree={item} /> : null}
</li>
)
})}
</ul>
) : null
}
<Toc tree={tableOfContents} />
If you want to add the table of contents to your MdxNode
, you can do so as follows:
import { TableOfContents } from "next-mdx-toc"
import { MdxNode } from "next-mdx/server"
interface Doc extends MdxNode {
toc: TableOfContents
}
Licensed under the MIT license.