# Add Table of Contents URL: /docs/theming/recipes/table-of-contents/ Section: recipes Tags: cookbook, toc, navigation -------------------------------------------------------------------------------- Add Table of Contents Bengal automatically generates a table of contents from page headings. Access it via page.toc. The Pattern 1 2 3 4 5 6{% if page.toc %} <nav class="toc" aria-label="On this page"> <h2>On this page</h2> {{ page.toc | safe }} </nav> {% endif %} That's it. Bengal parses headings and generates nested HTML lists. What's Happening Component Purpose page.toc Pre-rendered HTML list of headings \| safe Render as HTML, not escaped text Control Which Headings Configure in bengal.toml: 1 2 3[markup.toc] start_level = 2 # Start at H2 (skip H1 page title) end_level = 3 # Stop at H3 Variations Per-Page Disable 1 2 3 4--- title: Simple Page toc: false --- Then in template: 1 2 3{% if page.toc and page.metadata.toc != false %} {{ page.toc | safe }} {% endif %} With Article Layout 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<div class="article-layout"> <aside class="sidebar"> {% if page.toc %} <nav class="toc"> <h2>On this page</h2> {{ page.toc | safe }} </nav> {% endif %} </aside> <article> <h1>{{ page.title }}</h1> {{ page.rendered_html | safe }} </article> </div> Conditional by Section 1 2 3 4 5 6{# Only show TOC for docs section #} {% if page.section == 'docs' and page.toc %} <nav class="toc"> {{ page.toc | safe }} </nav> {% endif %} Scroll Highlighting (JavaScript) Highlight current section as user scrolls — this part is standard JS, not Bengal-specific: 1 2 3 4 5 6 7 8 9 10const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { document.querySelectorAll('.toc a').forEach(a => a.classList.remove('active')); document.querySelector(`.toc a[href="#${entry.target.id}"]`)?.classList.add('active'); } }); }, { rootMargin: '-20% 0px -80% 0px' }); document.querySelectorAll('h2[id], h3[id]').forEach(h => observer.observe(h)); Info Seealso Template Variables — All page properties Configuration — Markup options -------------------------------------------------------------------------------- Metadata: - Author: lbliii - Word Count: 292 - Reading Time: 1 minutes