Simple Table of Contents generator for DOM and Markdown.
import { domToc } from 'simpletoc'
const toc = domToc({
// Only search for content in a specific place.
root: '.content',
// Only use headings from 1 to 3 levels.
headings: 'h1, h2, h3',
// Where to place the generated Table of Contents.
target: '.table-of-contents-placeholder',
// Use an unordered list (bullet list, no numbers).
type: 'ul',
})import { mdToc } from 'simpletoc'
const output = mdToc(markdownText, {
// Place to inject the generated table of contents.
target: /Table of contents here/,
// Use an unordered list (bullet list, no numbers).
type: 'ul',
})You can also extract and render TOC items separately:
import { domItems, domList } from 'simpletoc'
const items = domItems({
root: document.querySelector('.content'),
headings: document.querySelectorAll('.content h2, .content h3'),
})
const toc = domList(items, {
render(items, { document, renderList }) {
const nav = document.createElement('nav')
nav.className = 'table-of-contents'
nav.appendChild(renderList(items))
return nav
},
})
document.querySelector('.table-of-contents-placeholder').replaceChildren(toc)Markdown items use the same normalized shape:
import { mdItems, mdList } from 'simpletoc'
const items = mdItems(markdownText)
const toc = mdList(items, { type: 'ul' })Main exports:
domToc(options)mdToc(text, options)domItems(options)mdItems(text, options)domList(items, options)mdList(items, options)
domItems() and mdItems() return normalized TocItem[] data:
type TocItem<TSource = unknown> = {
level: number
text: string
id: string
href: string
source: TSource
children: TocItem<TSource>[]
}DOM notes:
rootaccepts a CSS selector or anElementheadingsaccepts a CSS selector or an iterable/list ofElementtargetaccepts a CSS selector or anElementdomList()returns the root list element, so styling can be applied directlydomToc()forwardsrendertodomList()for custom rendering
Breaking changes from v1:
selectorwas renamed toheadingsdomList()andmdList()now takeTocItem[]domItems()andmdItems()are the new extraction APIs- DOM class options and old
getId/getAnchorhooks were removed in favor ofrender
I needed to generate a table of contents and all I found was kind of overkill or bulked.
$ pnpm add simpletocsimpletoc is ESM-only.
You can also use it straight from a CDN with esm.sh:
<script type="module">
import { domToc } from 'https://esm.sh/simpletoc'
domToc()
</script>If you only need one side of the library, use the subpath exports:
<script type="module">
import { domToc } from 'https://esm.sh/simpletoc/dom'
</script>Check the examples/ folder for more browser examples.
simpletoc targets Node.js 24+ and browsers in the current
baseline widely available
set.
- https://github.com/gajus/contents
- https://github.com/jgallen23/toc
- https://github.com/gfranko/jquery.tocify.js
- https://github.com/tscanlin/tocbot
- https://github.com/n1k0/toctoc
- https://github.com/aslushnikov/table-of-contents-preprocessor
- https://github.com/Oktavilla/markdown-it-table-of-contents
- https://github.com/gajus/markdown-contents
- https://github.com/thlorenz/doctoc
Please read CONTRIBUTING.md. ♥
MIT ♥