Browse docs
Browse docs
A horizontal "you are here" trail. Pure presentational — doesn't know about your router, your URL parser, or your route shape. You pass items: BreadcrumbItem[], it renders them with a configurable separator. The last crumb gets aria-current="page". Long paths can collapse the middle into an ellipsis (maxItems controls it).
import { Breadcrumbs } from '@dashforge/tw';
<Breadcrumbs
items={[
{ id: 'home', label: 'Home', href: '/' },
{ id: 'settings', label: 'Settings', href: '/settings' },
{ id: 'team', label: 'Team', href: '/settings/team' },
{ id: 'members', label: 'Members' }, // last crumb — no href, gets aria-current
]}
/>Standalone:
<Breadcrumbs
items={[
{ id: 'docs', label: 'Docs', href: '/docs' },
{ id: 'components', label: 'Components', href: '/docs/components' },
{ id: 'breadcrumbs', label: 'Breadcrumbs' },
]}
/>With a router (react-router-dom here, but any link component works):
import { Link } from 'react-router-dom';
<Breadcrumbs
linkComponent={Link}
items={[
{ id: 'home', label: 'Home', to: '/' },
{ id: 'workspace', label: 'Workspace', to: '/workspace' },
{ id: 'settings', label: 'Settings' },
]}
/>Whatever prop the router uses (href, to, route, …) passes through — Breadcrumbs is agnostic.
import { Breadcrumbs } from '@dashforge/tw';
<Breadcrumbs
items={[
{ id: 'home', label: 'Home', href: '/' },
{ id: 'settings', label: 'Settings', href: '/settings' },
{ id: 'team', label: 'Team', href: '/settings/team' },
{ id: 'members', label: 'Members' }, // last crumb — aria-current="page"
]}
/><Breadcrumbs separator="·" items={ITEMS} />
<Breadcrumbs separator="→" items={ITEMS} />
<Breadcrumbs separator={<ChevronRightIcon className="h-4 w-4" />} items={ITEMS} />Default is /. Pass any string, number, or React node.
When the trail gets long, collapse the middle to …:
<Breadcrumbs
maxItems={4}
itemsBeforeCollapse={1}
itemsAfterCollapse={2}
items={[
{ id: 'home', label: 'Home', href: '/' },
{ id: 'org', label: 'Org', href: '/org' },
{ id: 'workspace', label: 'Workspace', href: '/org/ws' },
{ id: 'folder', label: 'Folder', href: '/org/ws/folder' },
{ id: 'subfolder', label: 'Subfolder', href: '/org/ws/folder/sub' },
{ id: 'document', label: 'Document' },
]}
/>
{/* Renders: Home / … / Subfolder / Document */}maxItems is the threshold above which collapse triggers. itemsBeforeCollapse and itemsAfterCollapse control how many crumbs survive on each side. First + last always preserved.
<Breadcrumbs size="sm" items={ITEMS} />
<Breadcrumbs size="md" items={ITEMS} /> {/* default */}
<Breadcrumbs size="lg" items={ITEMS} /><AppShell
header={
<TopBar
start={<Brand />}
center={<Breadcrumbs items={[...]} />}
end={<UserMenu />}
/>
}
...
/>| Prop | Type | Default | Description |
|---|---|---|---|
items | BreadcrumbItem[] | — | The crumb trail. See the BreadcrumbItem shape below. |
separator | ReactNode | '/' | Between-crumb separator. |
maxItems | number | 0 (never collapse) | Threshold for middle-collapse. |
itemsBeforeCollapse | number | 1 | Crumbs kept at the start when collapsing. |
itemsAfterCollapse | number | 1 | Crumbs kept at the end when collapsing. |
linkComponent | ComponentType | 'a' | Router-agnostic — pass your Link component. |
ariaLabel | string | 'Breadcrumb' | Nav aria-label. |
size | 'sm' | 'md' | 'lg' | 'md' | Density. |
slotProps | BreadcrumbsSlotProps | — | Per-slot overrides. |
sx | string | — | Utility-class override on root. |
root · list · item · link · current · separator · ellipsis
type BreadcrumbItem = {
id: string; // stable React key + accessibility id
label: ReactNode;
href?: string; // used if linkComponent is 'a'
to?: string; // used if linkComponent is a router Link
icon?: ReactNode; // optional inline icon
// …any extra props pass through to the linkComponent
};<nav aria-label="Breadcrumb"><ol>…</ol></nav> (semantic structure that screen readers recognize).items is treated as the current page — it doesn't get a link, it gets aria-current="page". If you pass a href / to on the last item, it's ignored.linkComponent: pass React Router's Link, Next.js's Link, Remix's Link, or your custom one. The component receives all extra props on each BreadcrumbItem (so { to: '/x' } works for React Router; { href: '/x' } for Next).<Button> next to the trail.sx="truncate" on the root or use maxItems aggressively (e.g. maxItems={3}).