1.1.5 • Public • Published


This Eleventy plugin will generate a TOC from page content using an Eleventy filter.

Default Options

  tags: ['h2', 'h3', 'h4'], // which heading tags are selected headings must each have an ID attribute
  wrapper: 'nav',           // element to put around the root `ol`/`ul`
  wrapperClass: 'toc',      // class for the element around the root `ol`/`ul`
  ul: false,                // if to use `ul` instead of `ol`
  flat: false,              // if subheadings should appear as child of parent or as a sibling


1. Install the plugin

npm i --save eleventy-plugin-toc

2. Make sure your headings have anchor IDs

Your heading elements must have ids before this plugin will create a TOC. If there aren't ids on your headings, there will be no anchors for this plugin to link to.

I use markdown-it-anchor to add those ids to the headings: Eleventy config example

// .eleventy.js

const markdownIt = require('markdown-it')
const markdownItAnchor = require('markdown-it-anchor')

module.exports = eleventyConfig => {
  // Markdown
  // ... your other Eleventy config options

3. Add this plugin to your Eleventy config

// .eleventy.js

const pluginTOC = require('eleventy-plugin-toc')

module.exports = function (eleventyConfig) {

3.1 You can override the default plugin options

module.exports = function (eleventyConfig) {
  eleventyConfig.addPlugin(pluginTOC, {
    tags: ['h2', 'h3'],
    wrapper: 'div'

4. Use the filter in your layout template(s)

Because Eleventy only provides the content variable to layout templates (not to content files), you'll need to put this markup in a layout template:

  {{ content }}
  {{ content | toc }}

If you're using Nunjucks, include the safe filter:

  {{ content | safe }}
  {{ content | toc | safe }}

If you want to conditionally render a wrapper element, the filter will return undefined when no markup is generated:

{% if content | toc %}
    {{ content | toc }}
{% endif %}

5. Override default options if necessary

Pass a stringified JSON object (must be JSON.parse()-able) as an option for in your template. Because this is an object, you only need to include the key-value pairs you need to override; defaults will be preserved.

  {{ content | toc: '{"tags":["h2","h3"],"wrapper":"div","wrapperClass":"content-tableau"}' }}


  • [ ] Some tests would be nice

Package Sidebar


npm i eleventy-plugin-toc

Weekly Downloads






Unpacked Size

10.1 kB

Total Files


Last publish


  • jdsteinbach