Breadcrumb
A Breadcrumb shows users where the current page is in a hierarchy and links to each level above it.
When to Use
- for the top of a page that is under other pages, such as an invoice under its client
- to name the workspace and the current page in the header of an app
When Not to Use
- for the main links of a site, as a Breadcrumb shows one path and not the pages next to it (use a Navigation Menu)
- for the sections of an app (use a Sidebar)
- for the pages of a list (use Pagination)
Anatomy
| Element | Usage |
|---|---|
| Link | Optional |
| Separator | Between two items |
| Ellipsis | Optional |
| Current page | Required |
BreadcrumbSeparator renders a caret, and its children replace the caret. The list doesn’t add separators, so place a BreadcrumbSeparator between every two items.
Behavior
The current page has no href.
Wrapping
When the items don’t fit on one row, the list wraps, and a separator can start a row. A name wraps between its words.
Collapsing
BreadcrumbEllipsis has no behavior of its own. You choose the levels that it replaces.
Content
| String | Rule | Example | Counterexample |
|---|---|---|---|
| Link | The name of the page it opens | “Atelier Brume” | “Client” |
| Current page | The name of the record or page in view | “INV-2026-014” | “Details” |
The aria-label of Breadcrumb is labels.breadcrumb.label, which is “breadcrumb” by default. BreadcrumbEllipsis contains labels.breadcrumb.more, which is “More” by default. To translate both, use the Summit Provider.
Accessibility
A Breadcrumb renders a named nav that contains an ordered list of links. The links are native a elements, so the browser provides their role and their keys.
Roles and Labels
| Part | Element | Semantics |
|---|---|---|
Breadcrumb | nav | A navigation landmark named by aria-label |
BreadcrumbPage | span | role="link", aria-disabled="true", and aria-current="page" |
BreadcrumbSeparator | li | role="presentation" and aria-hidden="true" |
BreadcrumbEllipsis | span | role="presentation". Its icon has aria-hidden, and its label is visually hidden text. |
Requirements
Use a BreadcrumbPage for the last item, not a link, so that the item has aria-current="page".
BreadcrumbPage for the last item so that it is marked as the current page.aria-current, so users can’t tell which item is the current page.If the ellipsis opens the levels that it replaces, place it in a button with an aria-label so that screen readers
can announce the button, as WCAG 2.2 SC 4.1.2 Name, Role, Value requires.
Installation
npx shadcn@latest add @summit/breadcrumbThe CLI also adds @summit/summit-provider.
Usage
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/components/ui/breadcrumb';
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/clients">Clients</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/clients/atelier-brume">Atelier Brume</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>INV-2026-014</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>;With a Router Link
To use a router’s link in place of the a, pass it to render on BreadcrumbLink.
import Link from 'next/link';
<BreadcrumbLink render={<Link href="/clients" />}>Clients</BreadcrumbLink>;With a Custom Separator
To replace the caret, pass the separator as children of BreadcrumbSeparator. In a right-to-left layout, the caret points left, but a separator passed as children isn’t mirrored. See Iconography for the rule.
<BreadcrumbSeparator>/</BreadcrumbSeparator>Hide a Level on a Narrow Screen
To hide a level on a narrow screen, add a class to its item and its separator that shows them only from a breakpoint.
<BreadcrumbItem className="hidden md:inline-flex">
<BreadcrumbLink href="/">Studio Lumen</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator className="hidden md:block" />Collapse Levels Into a Menu
To collapse levels into a menu, place the ellipsis in the trigger of a Dropdown Menu and set an aria-label on the Button. Pass an a to render on each item so that a click or Enter follows the link.
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="ghost" size="icon-xs" aria-label="Show hidden levels" />}>
<BreadcrumbEllipsis />
</DropdownMenuTrigger>
<DropdownMenuContent className="w-40">
<DropdownMenuItem render={<a href="/clients/atelier-brume" />}>Atelier Brume</DropdownMenuItem>
<DropdownMenuItem render={<a href="/clients/atelier-brume/invoices" />}>Invoices</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>;API Reference
The parts accept the props of the elements that they render. BreadcrumbLink also accepts render. See the Base UI useRender documentation for render.