![GitHub Sponsors](https://img.shields.io/github/sponsors/tscanlin)
Tocbot builds a table of contents (TOC) from headings in an HTML document. This is useful for documentation websites or long markdown pages because it makes them easier to navigate. This library was inspired by Tocify, the main difference is that Tocbot uses native DOM methods and avoids the jQuery & jQuery UI dependencies.
Get Started
You can use npm to install it or include the script on the page with HTML.
Download it here
Include JS
Install it with npm.
npm install --save tocbot
OR
Include the script at the bottom of the page before the closing body tag.
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.18.2/tocbot.min.js"></script>
Include CSS
CSS is used for expanding & collapsing groupings and some basic styling.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.18.2/tocbot.css">
OR
If you installed it with npm and use sass / postcss you might try importing the styles from 'node_modules', see the includePath option documentation for more info
@import 'tocbot/src/scss/tocbot';
Usage
Initialize the script at the bottom of the page before the closing body tag.
tocbot.init({
tocSelector: '.js-toc',
contentSelector: '.js-toc-content',
headingSelector: 'h1, h2, h3',
hasInnerContainers: true,
});
NOTE: Make sure the body is scrollable and the document headings have id attributes, tocbot and your browser needs these things to make hashes jump to the proper heading, some markdown libraries (like marked) already do this for you.
If content in the div has changed then trigger a refresh (optionally with new options).
tocbot.refresh();
Also you can use it within typescript:
import * as tocbot from 'tocbot';
tocbot.init({
});
tocbot.refresh();
tocbot.destroy();
Examples
If you'd like to add your page to this list open a pull request.
Requirements
This library uses vanilla JavaScript. It is less than 350 bytes of CSS and about 3.6Kb of JavaScript (minified and gzipped) it also has no dependencies.
This script works in all modern browsers and IE 9+.
Make sure rendered headings have id attributes, some markdown libraries (like marked) already do this. If you need to do this client side see this script.
NOTE: to exclude anchor elements from smooth scrolling, add the class no-smooth-scroll
.
To handle fixed headers with tocbot, just pass the header offsets as options to tocbot. For example, the options needed for a 40px
tall fixed header would be:
tocbot.init({
headingsOffset: 40,
scrollSmoothOffset: -40
})
API
Options
tocSelector: '.js-toc',
tocElement: element,
contentSelector: '.js-toc-content',
contentElement: element,
headingSelector: 'h1, h2, h3',
ignoreSelector: '.js-toc-ignore',
hasInnerContainers: false,
linkClass: 'toc-link',
extraLinkClasses: '',
activeLinkClass: 'is-active-link',
listClass: 'toc-list',
extraListClasses: '',
isCollapsedClass: 'is-collapsed',
collapsibleClass: 'is-collapsible',
listItemClass: 'toc-list-item',
activeListItemClass: 'is-active-li',
collapseDepth: 0,
scrollSmooth: true,
scrollSmoothDuration: 420,
scrollSmoothOffset: 0,
scrollEndCallback: function (e) {},
headingsOffset: 1,
throttleTimeout: 50,
positionFixedSelector: null,
positionFixedClass: 'is-position-fixed',
fixedSidebarOffset: 'auto',
includeHtml: false,
includeTitleTags: false,
onClick: function (e) {},
orderedList: true,
scrollContainer: null,
skipRendering: false,
headingLabelCallback: false,
ignoreHiddenElements: false,
headingObjectCallback: null,
basePath: '',
disableTocScrollSync: false,
tocScrollOffset: 0,
Methods
.init
Initialize tocbot with an options object.
tocbot.init(options)
.destroy
Destroy tocbot and remove event listeners.
tocbot.destroy()
.refresh
Refresh tocbot if the document changes and it needs to be rebuilt.
tocbot.refresh()
Troubleshooting
- Tocbot scrolls to the right position onClick but highlighting doesn't seem to show the active section
- Try running this from the console:
tocbot.refresh({ ...tocbot.options, hasInnerContainers: true })
. If that works then one option (hasInnerContainers: true
) to handle inner containers should be all you need to add.
Contributing
Contributions and suggestions are welcome! Please feel free to open an issue if you run into a problem or have a feature request. I'll do my best to respond in a timely fashion.
If you want to open a pull request just fork the repo but please make sure all tests and lint pass.
Running Tests
npm run test
Steps to publish
- Push a branch and open a pull request
- run
npm version <patch|minor|major>
- Update readme.md with notes
- Merge the pull request
- commit dist/
- run
npm publish
- make release on github
License
MIT