Scroll Spy
Automatically updates navigation links based on scroll position with support for nested sections and customizable behavior.
Installation
pnpm dlx shadcn@latest add @diceui/scroll-spyLayout
Import the parts, and compose them together.
import {
ScrollSpy,
ScrollSpyNav,
ScrollSpyLink,
ScrollSpyViewport,
ScrollSpySection,
} from "@/components/ui/scroll-spy";
return (
<ScrollSpy>
<ScrollSpyNav>
<ScrollSpyLink />
</ScrollSpyNav>
<ScrollSpyViewport>
<ScrollSpySection />
</ScrollSpyViewport>
</ScrollSpy>
)Examples
Vertical Orientation
Set orientation="vertical" for content with vertical navigation.
Controlled State
Use the value and onValueChange props to control the active section externally.
Sticky Layout
For full-page scroll behavior, you can use a sticky positioned navigation sidebar that stays fixed while the content scrolls. This works with the default window scroll (no scrollContainer prop needed).
<ScrollSpy offset={100}>
<ScrollSpyNav className="sticky top-20 h-fit">
<ScrollSpyLink value="introduction">Introduction</ScrollSpyLink>
<ScrollSpyLink value="getting-started">Getting Started</ScrollSpyLink>
<ScrollSpyLink value="usage">Usage</ScrollSpyLink>
<ScrollSpyLink value="api-reference">API Reference</ScrollSpyLink>
</ScrollSpyNav>
<ScrollSpyViewport>
<ScrollSpySection value="introduction">
<h2>Introduction</h2>
<p>Your content here...</p>
</ScrollSpySection>
<ScrollSpySection value="getting-started">
<h2>Getting Started</h2>
<p>Your content here...</p>
</ScrollSpySection>
{/* More content sections */}
</ScrollSpyViewport>
</ScrollSpy>The key is to apply sticky top-[offset] to the ScrollSpyNav to keep the navigation visible as the page scrolls.
API Reference
ScrollSpy
The root component that manages scroll tracking and contains all ScrollSpy parts.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-orientation] | "horizontal" | "vertical" |
Nav
The navigation container component.
| Data Attribute | Value |
|---|---|
[data-orientation] | "horizontal" | "vertical" |
Link
Navigation link that scrolls to a section.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-orientation] | "horizontal" | "vertical" |
[data-state] | "active" | "inactive" |
Viewport
The viewport container component for sections.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-orientation] | "horizontal" | "vertical" |
Section
Content section that gets tracked by the scroll spy.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-orientation] | "horizontal" | "vertical" |
Accessibility
Keyboard Shortcuts
The ScrollSpy component follows standard link navigation patterns:
| Key | Description |
|---|---|
| Tab | Move focus between navigation items. |
| Enter | Activate the focused navigation item and scroll to the associated section. |
| Space | Activate the focused navigation item and scroll to the associated section. |