<table-of-contents></table-of-contents>
A lightweight Table of contents generator, distributed as a web component.
Features:
- Takes all headlines of a webpage or article and turns them into semantically correct nested lists
- Selection of headlines can be specified by providing the
selector
attribute, which usesquerySelectorAll
- Handles complex cases: headlines not ordered as expected, but h3 followed by h2 etc.
- Does NOT use shadow DOM for easy styling and to inherit the style of your page/article; does not come with its own style
- Adds links to list items, if a headline has an
id
attribute - Can be provided with custom HTML to add a header, footer or wrap the entire list in a
<details>
tag (see Examples) - Zero-dependencies
Via npm:
npm install table-of-contents-element
import 'table-of-contents-element';
Or as a <script>
tag:
<script type="module" src="https://cdn.jsdelivr.net/npm/table-of-contents-element/index.js"></script>
Then use the HTML:
<table-of-contents></table-of-contents>
Including the script automatically defines the custom element.
<table-of-contents></table-of-contents>
<table-of-contents selector="article h2, article h3:not(.newsletter-signup)"></table-of-contents>
Or target only headlines that have an id
attribute:
<table-of-contents selector="h1[id], h2[id], h3[id], h4[id]"></table-of-contents>
<table-of-contents listtype="ol"></table-of-contents>
You can give any child element an attribute called data-toc-render-target
to specify where the list items should be rendered. This way, you can wrap the table of contents in a <details>
tag:
<table-of-contents>
<details>
<summary>Table of contents</summary>
<div data-toc-render-target></div>
</details>
</table-of-contents>
Or add a <header>
and <footer>
to your table of contents:
<table-of-contents>
<header>Table of contents</header>
<div data-toc-render-target></div>
<footer>powered by table-of-contents-element</footer>
</table-of-contents>
If you do not provide an attribute data-toc-render-target
, the generated list will be added as the last child:
<table-of-contents>
<header>Table of contents</header>
<!-- toc list will be placed here -->
</table-of-contents>
If you need to re-create the table of contents, for example, because the article content changed dynamically, you can call render()
:
const toc = document.getElementsByTagName('table-of-contents')[0];
toc.render(); // recreates the TOC
The table-of-contents
custom element can be created via JS:
const toc = document.createElement('table-of-contents');
toc.setAttribute('selector', 'h2, h3, h4');
document.body.appendChild(toc);
Please note that <table-of-contents>
does not observe changes to attributes. In the rare case that you need to change attributes, simply destroy the existing element and re-create it.
Method | Description |
---|---|
render() |
Recreates the table of contents |
Attribute | Values | Default | Description |
---|---|---|---|
listtype |
"ul" or "ol" | "ul" | List type for items |
selector |
whatever querySelectorAll() accepts | "h1, h2, h3, h4" | Query selector for headlines to generate the TOC from |
None. Note: Attributes are not reflected to properties.