TableOfContents
The sections of a long page as in-page links in a named nav; one level of nesting and a current marker.
Last updated
Show codeHide code
<TableOfContents items={[
{ label: 'Introduction', href: '#introduction' },
{ label: 'Software and tools', href: '#software-and-tools', children: [{ label: 'Our stack', href: '#our-stack' }] },
{ label: 'Conclusion', href: '#conclusion' },
]} current="#introduction" />Add
npx @ava-ui/apogee add table-of-contents
No dependencies. Zero JS.
Usage
Build the items from your headings (Astro’s render() returns them):
---
import TableOfContents from '@/components/apogee/TableOfContents/TableOfContents.astro'
const { headings } = await render(entry)
const items = headings.filter((h) => h.depth === 2).map((h) => ({ label: h.text, href: `#${h.slug}` }))
---
<TableOfContents items={items} />
API
| Prop | Type | Default | Description |
|---|---|---|---|
items |
{ label, href, children? }[] |
— | Required. children nest one level. |
label |
string |
'Table of contents' |
The visible heading and the nav’s name. |
current |
string |
— | href of the section to mark as current (aria-current="location"). |
class |
string |
— | Extra classes on the <nav>, merged last. |
States
- Current — the matching link turns primary and bold.
- Hover — links darken.
Examples
Beside an article: Split image 01.
Accessibility
- A
<nav>named bylabel; the visible heading repeats it for sighted readers (hidden from screen readers so it is not read twice). - The current section carries
aria-current="location".
Tokens
| Token | Used for |
|---|---|
--foreground-primary |
Heading and the current link |
--foreground-neutral-faded / --foreground-neutral |
Links / hover |
Do / Don’t
- Do use it on pages long enough to scroll several screens.
- Don’t list every heading; the second level is plenty.
Content
- Use the headings’ own words, so the link matches what the reader lands on.
Related
ShareLinksWays to pass a page on; Copy link, the device's share sheet and email.
NavLinkA navigation link that auto-detects and styles the current route, with prefix matching, external links and a collapsible NavGroup.
ProseTypography styling for a block of rich, CMS, or markdown HTML you don't control element by element.