Auto-Generated
Creates TOC from page headings automatically
Auto-generated table of contents from page headings. Sidebar for desktop, collapsible for mobile. Tracks active section on scroll.
TableOfContents is a smart navigation component for long-form content. It automatically generates a table of contents from your page's headings, tracks which section is currently visible, and provides quick jump links.
Three variants available: sidebar (sticky navigation on desktop), inline (embedded in content), and collapsible (expandable section for mobile). The component intelligently shows H2 + H3 headings for short content, or H2-only for pages with many headings.
Best for desktop layouts. Creates a sticky sidebar that follows scroll.
---
import TableOfContents from '@theme/components/ui/TableOfContents.astro';
// Astro automatically provides headings from content
const { headings } = Astro.props.entry;
---
<div class="lg:grid lg:grid-cols-[1fr_250px] lg:gap-8">
<article class="prose dark:prose-invert">
<!-- Your content here -->
</article>
<aside class="hidden lg:block">
<TableOfContents headings={headings} variant="sidebar" />
</aside>
</div> Perfect for mobile. Starts collapsed, expands when clicked.
<div class="lg:hidden mb-8">
<TableOfContents headings={headings} variant="collapsible" />
</div>
<article class="prose dark:prose-invert">
<!-- Your content -->
</article> Embedded in content flow. Shows at the top of the article.
<article class="prose dark:prose-invert">
<TableOfContents headings={headings} variant="inline" />
<!-- Rest of your content -->
</article> Responsive TOC: collapsible on mobile, sidebar on desktop
---
import Layout from '@theme/layouts/Layout.astro';
import TableOfContents from '@theme/components/ui/TableOfContents.astro';
// For content collections
import { getEntry } from 'astro:content';
const entry = await getEntry('blog', 'my-post');
const { Content, headings } = await entry.render();
---
<Layout title={entry.data.title}>
<div class="container mx-auto px-4 py-16">
<!-- Mobile TOC -->
<div class="lg:hidden mb-8">
<TableOfContents headings={headings} variant="collapsible" />
</div>
<!-- Desktop Layout -->
<div class="lg:grid lg:grid-cols-[1fr_250px] lg:gap-8">
<article class="prose prose-lg dark:prose-invert">
<Content />
</article>
<!-- Desktop Sidebar TOC -->
<aside class="hidden lg:block">
<TableOfContents headings={headings} variant="sidebar" />
</aside>
</div>
</div>
</Layout> headings -
Array of heading objects from Astro (required)
variant - Display
variant: "sidebar", "inline", or "collapsible" (default: "sidebar")
The component automatically adjusts heading depth:
The TOC highlights the currently visible section as the user scrolls. This requires headings to have proper IDs (Astro handles this automatically for markdown/MDX content).
Creates TOC from page headings automatically
Highlights current section on scroll
Sidebar, inline, and collapsible modes
Adjusts heading depth based on content length
Make long content navigable with auto-generated table of contents.