breadcrumb
Displays the path to the current resource using a hierarchy of links.
Philosophy
Breadcrumbs answer "where am I?" — the most basic navigation question. We keep the API declarative (BreadcrumbList -> BreadcrumbItem -> BreadcrumbLink) rather than generating breadcrumbs from routes because not every route maps cleanly to a breadcrumb trail. The Separator and Ellipsis sub-components handle the visual connecting tissue.
Installation
npx @gentleduck/cli add breadcrumb
npx @gentleduck/cli add breadcrumb
Usage
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb><Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>Examples
Custom separator
Use a custom component as children for <BreadcrumbSeparator /> to create a custom separator.
import { SlashIcon } from "lucide-react"
...
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<SlashIcon />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>import { SlashIcon } from "lucide-react"
...
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<SlashIcon />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>Dropdown
You can compose <BreadcrumbItem /> with a <DropdownMenu /> to create a dropdown in the breadcrumb.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
...
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger>
Components
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem>Documentation</DropdownMenuItem>
<DropdownMenuItem>Themes</DropdownMenuItem>
<DropdownMenuItem>GitHub</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
...
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger>
Components
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem>Documentation</DropdownMenuItem>
<DropdownMenuItem>Themes</DropdownMenuItem>
<DropdownMenuItem>GitHub</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>Collapsed
We provide a <BreadcrumbEllipsis /> component to show a collapsed state when the breadcrumb is too long.
import { BreadcrumbEllipsis } from "@/components/ui/breadcrumb"
...
<Breadcrumb>
<BreadcrumbList>
{/* ... */}
<BreadcrumbItem>
<BreadcrumbEllipsis />
</BreadcrumbItem>
{/* ... */}
</BreadcrumbList>
</Breadcrumb>import { BreadcrumbEllipsis } from "@/components/ui/breadcrumb"
...
<Breadcrumb>
<BreadcrumbList>
{/* ... */}
<BreadcrumbItem>
<BreadcrumbEllipsis />
</BreadcrumbItem>
{/* ... */}
</BreadcrumbList>
</Breadcrumb>Link component
To use a custom link component from your routing library, you can use the asChild prop on <BreadcrumbLink />.
import Link from "next/link"
...
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="/">Home</Link>
</BreadcrumbLink>
</BreadcrumbItem>
{/* ... */}
</BreadcrumbList>
</Breadcrumb>import Link from "next/link"
...
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="/">Home</Link>
</BreadcrumbLink>
</BreadcrumbItem>
{/* ... */}
</BreadcrumbList>
</Breadcrumb>Responsive
Here's an example of a responsive breadcrumb that composes <BreadcrumbItem /> with <BreadcrumbEllipsis />, <DropdownMenu />, and <Drawer />.
It displays a dropdown on desktop and a drawer on mobile.
Responsive with Ellipsis
A responsive breadcrumb that collapses intermediate items behind an ellipsis, displaying a dropdown on desktop and a drawer on mobile.
Component Composition
API Reference
Breadcrumb
| Prop | Type | Default | Description |
|---|---|---|---|
dir | 'ltr' | 'rtl' | -- | Text direction override. Resolved via useDirection (dir prop -> DirectionProvider -> 'ltr'). |
separator | React.ReactNode | -- | Custom separator element between breadcrumb items |
className | string | -- | Additional class names to apply |
children | React.ReactNode | -- | Breadcrumb content (typically a BreadcrumbList) |
...props | React.HTMLProps<HTMLElement> | -- | Additional props to spread to the nav element |
BreadcrumbList
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names to apply |
children | React.ReactNode | -- | List of BreadcrumbItem elements |
...props | React.HTMLProps<HTMLOListElement> | -- | Additional props to spread to the ol element |
BreadcrumbItem
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names to apply |
children | React.ReactNode | -- | Item content (typically a BreadcrumbLink or BreadcrumbPage) |
...props | React.HTMLProps<HTMLLIElement> | -- | Additional props to spread to the li element |
BreadcrumbLink
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | -- | If true, uses the Slot component instead of rendering an <a> directly |
className | string | -- | Additional class names to apply |
children | React.ReactNode | -- | Link content |
...props | React.HTMLProps<HTMLAnchorElement> | -- | Additional props to spread to the a element |
BreadcrumbPage
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names to apply |
children | React.ReactNode | -- | Page content (rendered with aria-current="page") |
...props | React.ComponentPropsWithoutRef<'span'> | -- | Additional props to spread to the span element |
BreadcrumbSeparator
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names to apply |
children | React.ReactNode | <ChevronRight /> | Custom separator icon; defaults to a ChevronRight icon |
...props | React.ComponentPropsWithoutRef<'li'> | -- | Additional props to spread to the li element |
BreadcrumbEllipsis
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | 'More' | Accessible label used for aria-label on the ellipsis element |
className | string | -- | Additional class names to apply |
...props | React.ComponentPropsWithoutRef<'span'> | -- | Additional props to spread to the span element |
RTL Support
Direction is resolved through the shared primitives direction module. Use a local dir="rtl" override when the component exposes it, or set DirectionProvider at app/root level for global RTL/LTR behavior.