Skip to main content

TableOfContents

Indexes a long page and marks the section currently in view.

import { TableOfContents } from "@/fragments/ui";Source

Preview

<TableOfContents>
  <TableOfContents.Item id="introduction">Introduction</TableOfContents.Item>
  <TableOfContents.Item id="getting-started">Getting Started</TableOfContents.Item>
  <TableOfContents.Item id="installation" indent>Installation</TableOfContents.Item>
  <TableOfContents.Item id="configuration" indent>Configuration</TableOfContents.Item>
  <TableOfContents.Item id="api-reference">API Reference</TableOfContents.Item>

Installation

npx @usefragments/cli add tableofcontents

Writes src/fragments/ui/components/TableOfContents plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.

Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.

Anatomy

TableOfContents is a compound: import the root and reach its parts through dot notation.

  • TableOfContents.Item
  • TableOfContents.Group

Sections and their subsections, indented.

<TableOfContents>
  <TableOfContents.Item id="introduction">Introduction</TableOfContents.Item>
  <TableOfContents.Item id="getting-started">Getting Started</TableOfContents.Item>
  <TableOfContents.Item id="installation" indent>Installation</TableOfContents.Item>
  <TableOfContents.Item id="configuration" indent>Configuration</TableOfContents.Item>
  <TableOfContents.Item id="api-reference">API Reference</TableOfContents.Item>
  <TableOfContents.Item id="examples">Examples</TableOfContents.Item>
</TableOfContents>

Examples

Top-level Only

Drops subsections when the index would crowd.

<TableOfContents hideSubItems>
  <TableOfContents.Item id="overview">Overview</TableOfContents.Item>
  <TableOfContents.Item id="basic-usage" indent>Basic usage</TableOfContents.Item>
  <TableOfContents.Item id="advanced-usage" indent>Advanced usage</TableOfContents.Item>
  <TableOfContents.Item id="accessibility">Accessibility</TableOfContents.Item>
</TableOfContents>

Nested Groups

Collapsible categories with counts.

<TableOfContents title="Components">
  <TableOfContents.Item id="all" active>All</TableOfContents.Item>
  <TableOfContents.Group label="Primitives" trailing={<span>3</span>}>
    <TableOfContents.Item id="button">Button</TableOfContents.Item>
    <TableOfContents.Item id="card">Card</TableOfContents.Item>
    <TableOfContents.Item id="input">Input</TableOfContents.Item>

With Active Item

The current section stays marked while you read.

<TableOfContents>
  <TableOfContents.Item id="overview">Overview</TableOfContents.Item>
  <TableOfContents.Item id="setup" active>Setup</TableOfContents.Item>
  <TableOfContents.Item id="usage" indent>Basic Usage</TableOfContents.Item>
  <TableOfContents.Item id="advanced" indent>Advanced</TableOfContents.Item>
  <TableOfContents.Item id="props">Props</TableOfContents.Item>

Custom Title

Any heading in place of the default.

<TableOfContents title="Contents">
  <TableOfContents.Item id="chapter-1">Chapter 1: The Beginning</TableOfContents.Item>
  <TableOfContents.Item id="chapter-2">Chapter 2: The Middle</TableOfContents.Item>
  <TableOfContents.Item id="chapter-3">Chapter 3: The End</TableOfContents.Item>
</TableOfContents>

No Title

Bare list where the surrounding layout already says enough.

<TableOfContents hideTitle>
  <TableOfContents.Item id="section-a">Section A</TableOfContents.Item>
  <TableOfContents.Item id="section-b" active>Section B</TableOfContents.Item>
  <TableOfContents.Item id="section-c">Section C</TableOfContents.Item>
</TableOfContents>

API

Component props
Prop
Type
Default
Description
childrenRequirednodeNot setTableOfContents.Item or TableOfContents.Group elements
labelstringTable of contentsAccessible label for the nav landmark
titlestringOn This PageVisible title above the list
hideTitlebooleanfalseHide the visible title
hideSubItemsbooleanfalseHide indented items and nested groups

Accessibility

  • Uses <nav aria-label="Table of contents"> for landmark navigation
  • Active item is marked with aria-current="location"
  • All items are links with smooth scroll behavior
  • Group toggle is a real <button> with aria-expanded reflecting open state
  • Focus-visible ring on keyboard navigation

Guidance

Use when

  • Docs, articles, and other long reads
  • Reference pages with many sections
  • Filterable sidebars grouped by category
  • Anything past three headings

Avoid when

  • Pages with one or two sections
  • Site navigation (use Sidebar or Header)
  • Steps in an order (use Stepper)
  • BreadcrumbscomplementaryBreadcrumbs show hierarchy, TOC shows page sections
  • SidebarcomplementarySidebar for site nav, TOC for in-page nav
  • TabsalternativeTabs for switching views, TOC for scrolling to sections

Next steps