# Section nav (goodtabs UI)

A sticky row of anchor links that underlines the section in view.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/section-nav.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/section-nav`

## Usage

```tsx
import { SectionNav } from "@/components/ui/section-nav"

<SectionNav
  items={[
    { id: "overview", label: "Overview" },
    { id: "features", label: "Features" },
    { id: "pricing", label: "Pricing" },
  ]}
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| items | `{ id: string; label: string }[]` |  | The sections in page order. id must match the section's id attribute. |
| activeId | `string` |  | Controlled active id. Set it and the scroll spy switches off. |
| root | `RefObject<HTMLElement | null>` |  | A scrolling element to spy on and scroll, instead of the window. |
| sticky | `boolean` | `true` | Sticks to the top of its scroll container. |

## When to use

- A long product, settings or profile page with three to eight named sections
- Under a page header, so people can jump within the page without a sidebar
- When the links must fit on a phone: it scrolls sideways instead of wrapping

## When not to use

- For navigating between pages, use the navbar or a sidebar
- For nested headings in docs, use the table of contents rail
- When the page has one or two sections: a heading is enough

## Notes for agents

- Client component. The sections must already carry the ids you list; wrap each in an element with that id
- The spy allows for its own 40px height when sticky, and watches the top 40% of the scroll area below it
- With root set, clicks scroll that element; without it they are plain anchors, so give sections scroll-mt-10
- Pass sticky={false} inside a demo frame or when another sticky header already sits at the top

Docs: https://ui.goodtabs.co/components/section-nav