Breadcrumb
The path to the current page as a trail of links, composed from parts or built from a list.
Basic
Links to each ancestor; the current page is plain text with aria-current.
Code
<Breadcrumb>
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbLink href="/ui">Components</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem>
</Breadcrumb>Usage
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis } from "@elements/ui/breadcrumb";
<Breadcrumb>
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbLink href="/docs">Docs</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem>
</Breadcrumb>
<Breadcrumb items={trail} maxItems={4} />Examples
Custom separator
Put any Icon or text in BreadcrumbSeparator.
Code
<Breadcrumb>
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator><Icon name="slash" /></BreadcrumbSeparator>
<BreadcrumbItem><BreadcrumbLink href="/ui">Components</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator><Icon name="dot" /></BreadcrumbSeparator>
<BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem>
</Breadcrumb>Text separator
Text in BreadcrumbSeparator replaces the chevron too.
Code
<Breadcrumb>
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator>/</BreadcrumbSeparator>
<BreadcrumbItem><BreadcrumbLink href="/settings">Settings</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator>/</BreadcrumbSeparator>
<BreadcrumbItem><BreadcrumbPage>Profile</BreadcrumbPage></BreadcrumbItem>
</Breadcrumb>Collapsed
BreadcrumbEllipsis stands in for the middle of a long trail.
Code
<Breadcrumb>
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbEllipsis /></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbLink href="/ui">Components</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbPage>Breadcrumb</BreadcrumbPage></BreadcrumbItem>
</Breadcrumb>With a dropdown
The collapsed crumb opens a DropdownMenu of the hidden pages: arrow keys walk it, Escape returns to the crumb.
Code
<BreadcrumbItem>
<DropdownMenu align="start">
<button slot="trigger" aria-label="Show hidden pages"><BreadcrumbEllipsis /></button>
<DropdownMenuItem href="/docs">Documentation</DropdownMenuItem>
<DropdownMenuItem href="/themes">Themes</DropdownMenuItem>
<DropdownMenuItem href="https://github.com">GitHub</DropdownMenuItem>
</DropdownMenu>
</BreadcrumbItem>Icons
An icon-only link needs an aria-label.
Code
<BreadcrumbItem>
<BreadcrumbLink href="/" attrs={{ "aria-label": "Home" }}><Icon name="home" /></BreadcrumbLink>
</BreadcrumbItem>Customization
class styles the crumbs: here each one is a chip.
Code
<Breadcrumb class="crumb-chips">
<BreadcrumbItem><BreadcrumbLink href="/"><Icon name="home" /> Home</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbLink href="/catalog">Catalog</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbPage>Accessories</BreadcrumbPage></BreadcrumbItem>
</Breadcrumb>
/* app CSS */
.crumb-chips .breadcrumb-link,
.crumb-chips .breadcrumb-page {
padding: 0 var(--space-2);
min-height: var(--control-height-sm);
border-radius: var(--radius-pill);
background: var(--secondary);
color: var(--secondary-ink);
}
.crumb-chips .breadcrumb-link:hover { background: var(--secondary-hover); }From a list, collapsed
items builds the trail. Past maxItems the middle collapses into a button that shows it.
Code
<Breadcrumb maxItems={4} itemsBefore={1} itemsAfter={2} items={[
{ label: "Home", href: "/" },
{ label: "Projects", href: "/projects" },
{ label: "Elements", href: "/projects/elements" },
{ label: "Packages", href: "/projects/elements/packages" },
{ label: "ui", href: "/projects/elements/packages/ui" },
{ label: "Breadcrumb" },
]} />Text separator from a list
separatorText puts text between the entries of an items trail in place of the icon.
Code
<Breadcrumb separatorText="›" items={[
{ label: "Home", href: "/" },
{ label: "Catalog", href: "/catalog" },
{ label: "Accessories" },
]} />Collapsed icon
collapsedIcon swaps the icon on the ellipsis button.
Code
<Breadcrumb collapsedIcon="chevrons-right" maxItems={3} items={[...]} />Collapsed text entries
A middle entry without href is text. Expanding the trail focuses the first revealed link.
Code
<Breadcrumb maxItems={3} items={[
{ label: "Home", href: "/" },
{ label: "Archive" },
{ label: "2026", href: "/archive/2026" },
{ label: "October", href: "/archive/2026/10" },
{ label: "Report" },
]} />Current page as a link
When the last entry has an href, the current page stays a link with aria-current=page (APG). BreadcrumbLink takes current for the same in parts.
Code
<Breadcrumb items={[
{ label: "Home", href: "/" },
{ label: "Catalog", href: "/catalog" },
{ label: "Accessories", href: "/catalog/accessories" },
]} />
<Breadcrumb>
...
<BreadcrumbItem><BreadcrumbLink href="/catalog/accessories" current>Accessories</BreadcrumbLink></BreadcrumbItem>
</Breadcrumb>A new trail starts collapsed
Expanding belongs to one trail: after a navigation the next trail collapses again. Entries take attrs for their links.
Code
<Breadcrumb maxItems={3} items={state.onApi ? API_TRAIL : DOCS_TRAIL} />
const DOCS_TRAIL = [
{ label: "Docs", href: "/docs", attrs: { title: "Documentation home" } },
...
];Right to left
Separators point the other way.
Code
<div dir="rtl">
<Breadcrumb label="مسار التنقل" items={[...]} />
</div>Long labels
The trail wraps; at phone width nothing overflows.
Code
<Breadcrumb items={[
{ label: "Organization settings", href: "/org" },
{ label: "Billing and invoices", href: "/org/billing" },
{ label: "Payment methods on file", href: "/org/billing/methods" },
{ label: "Corporate card ending 4242" },
]} />Translated
label names the landmark and expandText names the ellipsis button, so the whole trail reads in the page's language.
Code
<Breadcrumb label="Ruta de navegación" expandText="Mostrar la ruta completa" maxItems={3} items={[
{ label: "Inicio", href: "/" },
{ label: "Proyectos", href: "/proyectos" },
{ label: "Elements", href: "/proyectos/elements" },
{ label: "Ajustes" },
]} />Labelled by a heading
attrs puts aria-labelledby on the nav, so a visible heading names the landmark (APG) and label is left off.
You are here
Code
<p id="trail-heading">You are here</p>
<Breadcrumb attrs={{ "aria-labelledby": "trail-heading" }}>
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem><BreadcrumbPage>Settings</BreadcrumbPage></BreadcrumbItem>
</Breadcrumb>