Breadcrumb
Navigation aid showing the current page's location in a hierarchy with customizable separators and sizes.
Playground
<script lang="ts">
import { Breadcrumb } from '@urbicon-ui/blocks';
const items = [
{ label: 'Home', href: '#' },
{ label: 'Store', href: '#' },
{ label: 'Audio', href: '#' },
{ label: 'Products', href: '#' },
{ label: 'Headphones', href: '#' },
{ label: 'AirPods Max' }
];
</script>
<Breadcrumb
{items}
/>01 Examples
Deep Hierarchy
href='#' + onclick: preventDefault to keep the docs scroll position — real consumers omit the onclick.<Breadcrumb items={deepItems} size="sm" />Collapsing Long Paths
maxItems to fold the middle of a deep trail into an expandable ellipsis (…). itemsBeforeCollapse / itemsAfterCollapse keep that many items at each end (the current page is always shown); clicking the ellipsis reveals the full path and moves focus to the first revealed item.<Breadcrumb items={veryDeepItems} maxItems={4} itemsBeforeCollapse={2} size="sm" />With a Leading Icon
icon to anchor the trail visually — pass the icon component itself (icon: HomeIcon), not its name. It renders inside the crumb's own link, sized with the trail, and is aria-hidden, so the item still announces as its label.<Breadcrumb items={iconHomeItems}>
{#snippet separator()}
<ChevronRightIcon size={14} />
{/snippet}
</Breadcrumb>Page Header Context
Settings
BetaManage your project configuration and preferences.
<div class="flex flex-col gap-2">
<Breadcrumb items={projectItems} size="sm">
{#snippet separator()}
<ChevronRightIcon size={14} />
{/snippet}
</Breadcrumb>
<div class="flex items-center gap-3">
<p class="text-text-primary text-2xl font-bold">Settings</p>
<Badge intent="warning" size="xs" variant="soft">Beta</Badge>
</div>
<p class="text-text-secondary text-sm">
Manage your project configuration and preferences.
</p>
</div>02 Customization
Pill Links
<Breadcrumb
items={basicItems}
slotClasses={{
link: 'rounded-full bg-surface-subtle px-2.5 py-0.5 no-underline hover:bg-surface-hover hover:no-underline',
currentPage: 'rounded-full bg-primary/10 text-primary-emphasis px-2.5 py-0.5'
}}
>
{#snippet separator()}
<ChevronRightIcon size={14} />
{/snippet}
</Breadcrumb>Glassmorphism
<Breadcrumb
unstyled
items={galleryItems}
class="flex items-center rounded-full border border-white/20 bg-white/15 px-4 py-2 text-sm backdrop-blur-md"
slotClasses={{
list: 'flex items-center gap-1',
item: 'inline-flex items-center',
link: 'text-white/80 hover:text-white transition-colors',
currentPage: 'font-semibold text-white',
separator: 'mx-2 text-white/40'
}}
>
{#snippet separator()}
<ChevronRightIcon size={14} />
{/snippet}
</Breadcrumb>Terminal Path
<Breadcrumb
unstyled
items={terminalItems}
class="flex items-center font-mono text-sm"
slotClasses={{
list: 'flex items-center',
item: 'inline-flex items-center',
link: 'text-emerald-400 hover:text-emerald-300 transition-colors',
currentPage: 'font-bold text-amber-400',
separator: 'mx-1 text-neutral-600'
}}
/>Fully Custom (unstyled)
<Breadcrumb
unstyled
items={docsItems}
class="text-text-primary flex items-center rounded-lg border-2 border-current px-4 py-2"
slotClasses={{
list: 'flex items-center gap-1',
item: 'inline-flex items-center',
link: 'text-xs font-bold uppercase tracking-widest text-text-secondary hover:text-text-primary transition-colors',
currentPage: 'text-xs font-bold uppercase tracking-widest text-primary',
separator: 'mx-2 text-border-default text-xs'
}}
>
{#snippet separator()}
<span>/</span>
{/snippet}
</Breadcrumb>To ship the pill or glass trail site-wide, register it as a BlocksProvider preset (presets.Breadcrumb) and apply it with preset on each instance — see Customization.
03 Accessibility
Built-in ARIA
Renders as a <nav> with aria-label="Breadcrumb" (customizable via prop). The
last item carries aria-current="page" to announce the current page. A
per-item icon is decorative — it renders inside an aria-hidden wrapper, so the crumb announces as its label alone. Individual items still support aria-label for accessible name overrides.
Keyboard
All breadcrumb links are standard <a> elements, fully focusable via Tab. Focus indicators use focus-visible: to only show on keyboard navigation.
Semantic Markup
Uses an ordered list (<ol>) inside the <nav> landmark, following the WAI-ARIA Breadcrumb pattern. Separators are marked aria-hidden="true" to avoid screen reader clutter.
Reduced Motion
Hover transitions on links respect prefers-reduced-motion via the design-token-based transition
duration.
04 API Reference
Prop | Type | Default | Description | |
|---|---|---|---|---|
items required | BreadcrumbItem[] | — | Ordered breadcrumb items (last item is current page) | |
aria-label | string | — | Accessible label for the nav element. Defaults to the localized accessibility.breadcrumb. | |
class | string | — | Additional CSS classes to apply to the Breadcrumb component | |
expandLabel | string | — | Accessible label for the "…" button that expands a collapsed trail.
Defaults to the localized accessibility.breadcrumbExpand. | |
itemsAfterCollapse | number | 1 | Trailing items kept visible when collapsed; the current page is always included. | |
itemsBeforeCollapse | number | 1 | Leading items kept visible when collapsed. | |
maxItems | number | — | Collapse the trail when it has more than this many items: the middle items
fold into a single "…" button that expands the full trail on click. The
first itemsBeforeCollapse and last itemsAfterCollapse items stay
visible (the current page is always kept). Omit to never collapse. | |
preset | string | — | Apply a named preset registered via <BlocksProvider presets={{ Breadcrumb: {...} }}>.
Prefer this over class overrides when the requested look falls outside the
semantic intent palette — presets keep hover/active/dark-mode logic coherent
and make the custom look reusable across the project. | |
separator | Snippet | — | Custom separator snippet (default: "/") | |
size | smmdlg | 'md' | Size variant that controls dimensions and spacing of the Breadcrumb | |
slotClasses | Partial<Record<BreadcrumbSlots, string>> | — | Per-slot class overrides | |
unstyled | boolean | — | Remove default styles | |
wrap | boolean | true | Let the trail wrap onto multiple lines (true, default) or keep it on a
single line where the current page truncates and the ancestor links hold
their width (false). Use false for tight single-line bars such as a
sticky header or toolbar. | |
...BreadcrumbVariants variant | VariantProps | — | Styling variants from BreadcrumbVariants | |
...HTMLAttributes<HTMLElement> inherited | HTMLAttributes | — | HTML attributes (excluding: 'children') |
05 Types
Local type definitions used by this component.
Name | Kind | Category | Used by | Description | |
|---|---|---|---|---|---|
BreadcrumbItem | interface | helper | 1 | Single breadcrumb item definition | |
BreadcrumbProps | interface | props | 0 | Props interface for Breadcrumb component | |
BreadcrumbVariants | type | variant | 1 | — | |
BreadcrumbSlots | type | variant | 0 | Slot names derived from the tv() config above — single source of truth for slotClasses. | |
IconComponent | type | helper | 0 | — | |
IconProps | interface | props | 0 | — |
06 Installation
Import
import { Breadcrumb } from '@urbicon-ui/blocks';