Skip to content

stefanmaric/simpletoc

Repository files navigation

simpletoc

Simple Table of Contents generator for DOM and Markdown.

license CI npm npm GitHub stars

Quick dive

For the DOM

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',
})

For Markdown

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' })

API

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:

  • root accepts a CSS selector or an Element
  • headings accepts a CSS selector or an iterable/list of Element
  • target accepts a CSS selector or an Element
  • domList() returns the root list element, so styling can be applied directly
  • domToc() forwards render to domList() for custom rendering

Breaking changes from v1:

  • selector was renamed to headings
  • domList() and mdList() now take TocItem[]
  • domItems() and mdItems() are the new extraction APIs
  • DOM class options and old getId / getAnchor hooks were removed in favor of render

Why?

I needed to generate a table of contents and all I found was kind of overkill or bulked.

Install

$ pnpm add simpletoc

simpletoc 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.

Browser support

simpletoc targets Node.js 24+ and browsers in the current baseline widely available set.

Some alternatives

Contributing

Please read CONTRIBUTING.md. ♥

License

MIT

About

Simple Table of Contents generator for DOM and Markdown

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors