Your Business Name
Skip to main content

TableOfContents - Navigate Long Content

Auto-generated table of contents from page headings. Sidebar for desktop, collapsible for mobile. Tracks active section on scroll.

What Is TableOfContents?

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.

Live Examples

Sidebar Variant

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>

Collapsible Variant

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>

Inline Variant

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>

How to Use TableOfContents

Complete Example

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>

Props Reference

  • headings - Array of heading objects from Astro (required)
  • variant - Display variant: "sidebar", "inline", or "collapsible" (default: "sidebar")

Smart Heading Selection

The component automatically adjusts heading depth:

  • ≤15 total headings: Shows H2 + H3 (detailed TOC)
  • >15 total headings: Shows only H2 (cleaner TOC)
  • This keeps the TOC readable regardless of content length

Active Section Tracking

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).

TableOfContents Features

Auto-Generated

Creates TOC from page headings automatically

Active Tracking

Highlights current section on scroll

Multiple Variants

Sidebar, inline, and collapsible modes

Smart Depth

Adjusts heading depth based on content length

Ready to Use TableOfContents?

Make long content navigable with auto-generated table of contents.