Breadcrumb
Overview
Breadcrumbs allow users to navigate through the hierarchy of pages. It displays the current location within the application structure.
Features
- Data-driven compact composition —
SBreadcrumbrenders items from anitemsarray; the AriaBreadcrumbCompactowns iteration, default content, and internal composition (root → list → items → separators). - Link vs. current page — items with
to/hrefrender asBreadcrumbLink(reusing the Link primitive); the trailing item without a destination renders asBreadcrumbPagewitharia-current="page"andaria-disabled. - Ellipsis collapsing —
ellipsis: truecollapses all middle items into an ellipsis when there are 5+ items;ellipsis: [start, end]allows a custom collapse range (normalized sostart 0 → 1andend length → length - 1). - Click events with item data — the
clickevent emits the full activated item object; disabled items never emit. - Full ARIA semantics —
navcarries a localizedaria-label; separators and the ellipsis arerole="presentation"+aria-hidden; the current page usesaria-current="page". - Per-region props forwarding —
listProps,itemProps,linkProps,pageProps,separatorProps,ellipsisPropsforward attributes to each region. - Eight customization slots —
default,ellipsis,ellipsis-icon,separator,item-leading,item-link,item-label,item-trailingwith typed scoped props (item,index,ellipsisItems). - Icon support — each item can carry an
icon(rendered via theitem-leadingslot default) withIconValuetyping. - Disabled items —
disabled: trueon an item disables the link and suppresses click emission. - Size scaling —
size(xs…2xl) scales typography and spacing viabreadcrumbVariants. - Aria composition —
BreadcrumbRoot/BreadcrumbList/BreadcrumbItem/BreadcrumbLink/BreadcrumbPage/BreadcrumbSeparator/BreadcrumbEllipsisare exported from@vean/aria/breadcrumbfor fully custom styled builds.
Usage
SBreadcrumbdelegates its list aggregation to AriaBreadcrumbCompact. For unstyled, data-driven composition, importBreadcrumbCompactfrom@vean/aria/breadcrumb.
Demos
Basic
Separator
Link
Item Dropdown
Ellipsis Dropdown
API
Aria Layer
11Breadcrumb<T>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
class | ClassValue | — | root class |
size | ThemeSize | — | Visual size of the component. |
ui | Partial<BreadcrumbUi> | — | Per-slot class overrides for the component. |
items | T[] | — | Items rendered by the component. |
ellipsis | true | [number, number] | null | — | The range of items to show ellipsis.
When the item count is greater than 4, we will show ellipsis. |
listProps | BreadcrumbListProps | — | Properties forwarded to the list element. |
itemProps | BreadcrumbItemProps | — | Properties forwarded to the item element. |
linkProps | LinkExtraProps | — | Properties forwarded to the link element. |
pageProps | BreadcrumbPageProps | — | Properties forwarded to the page element. |
separatorProps | BreadcrumbSeparatorProps | — | Properties forwarded to the separator element. |
ellipsisProps | BreadcrumbEllipsisProps | — | Properties forwarded to the ellipsis element. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
click | T | Emitted when click occurs. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
default | BreadcrumbCompactItemSlotProps<T> | Custom content for the default slot. |
ellipsis | BreadcrumbCompactEllipsisSlotProps<T> | Custom content for the ellipsis slot. |
ellipsis-icon | — | Custom content for the ellipsis icon slot. |
separator | — | Custom content for the separator slot. |
item-leading | BreadcrumbCompactItemSlotProps<T> | Custom content for the item leading slot. |
item-link | BreadcrumbCompactItemSlotProps<T> | Custom content for the item link slot. |
item-label | BreadcrumbCompactItemSlotProps<T> | Custom content for the item label slot. |
item-trailing | BreadcrumbCompactItemSlotProps<T> | Custom content for the item trailing slot. |
BreadcrumbCompact<T>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | T[] | — | Items rendered by the component. |
ellipsis | true | [number, number] | null | — | The range of items to show ellipsis.
When the item count is greater than 4, we will show ellipsis. |
listProps | BreadcrumbListProps | — | Properties forwarded to the list element. |
itemProps | BreadcrumbItemProps | — | Properties forwarded to the item element. |
linkProps | LinkExtraProps | — | Properties forwarded to the link element. |
pageProps | BreadcrumbPageProps | — | Properties forwarded to the page element. |
separatorProps | BreadcrumbSeparatorProps | — | Properties forwarded to the separator element. |
ellipsisProps | BreadcrumbEllipsisProps | — | Properties forwarded to the ellipsis element. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
click | T | Emitted when click occurs. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
default | BreadcrumbCompactItemSlotProps<T> | Custom content for the default slot. |
ellipsis | BreadcrumbCompactEllipsisSlotProps<T> | Custom content for the ellipsis slot. |
ellipsis-icon | — | Custom content for the ellipsis icon slot. |
separator | — | Custom content for the separator slot. |
item-leading | BreadcrumbCompactItemSlotProps<T> | Custom content for the item leading slot. |
item-link | BreadcrumbCompactItemSlotProps<T> | Custom content for the item link slot. |
item-label | BreadcrumbCompactItemSlotProps<T> | Custom content for the item label slot. |
item-trailing | BreadcrumbCompactItemSlotProps<T> | Custom content for the item trailing slot. |
BreadcrumbCompactEllipsis
BreadcrumbCompactItem
BreadcrumbEllipsis
BreadcrumbItem
BreadcrumbLink
Props
| Prop | Type | Default | Description |
|---|---|---|---|
to | string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric | — | Route Location the link should navigate to when clicked on. |
replace | boolean | — | Calls `router.replace` instead of `router.push`. |
href | string | — | The URL the link should navigate to when clicked on. |
disabled | boolean | — | When `true`, the link is disabled. |
activeClass | string | — | Class to apply when the link is active |
exactActiveClass | string | — | Class to apply when the link is exact active |
inactiveClass | string | — | The class to apply to the link when it is inactive. |
prefetchedClass | string | — | A class to apply to links that have been prefetched. |
external | boolean | — | Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases |
ariaCurrentValue | 'true' | 'false' | 'page' | 'date' | 'time' | 'step' | 'location' | `'page'` | Value passed to the attribute `aria-current` when the link is exact active. |
viewTransition | boolean | — | Pass the returned promise of `router.push()` to `document.startViewTransition()` if supported. |
target | (string & {}) | '_blank' | '_parent' | '_self' | '_top' | null | — | Where to display the linked URL, as the name for a browsing context. |
rel | (string & {}) | 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | null | 'noopener noreferrer' | A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links. |
noRel | boolean | — | If set to true, no rel attribute will be added to the link |
prefetch | boolean | — | When enabled will prefetch middleware, layouts and payloads of links in the viewport. |
prefetchOn | 'visibility' | 'interaction' | Partial<{ visibility: boolean; interaction: boolean; }> | — | Allows controlling when to prefetch links. By default, prefetch is triggered only on visibility. |
noPrefetch | boolean | — | Escape hatch to disable `prefetch` attribute. |
trailingSlash | 'append' | 'remove' | — | An option to either add or remove trailing slashes in the `href` for this specific link.
Overrides the global `trailingSlash` option if provided. |
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
BreadcrumbList
BreadcrumbPage
BreadcrumbRoot
BreadcrumbSeparator
Notes
Architecture and benchmark comparison
| Concern | VeanUI | shadcn-vue Breadcrumb | Ant Design Breadcrumb | Element Plus Breadcrumb |
|---|---|---|---|---|
| Aria / styled separation | ✅ @vean/aria/breadcrumb + scv() | ❌ single package | ❌ single package | ❌ single package |
| Data-driven compact API | ✅ items + ellipsis + click | ❌ slot/component composition only | ✅ routes / items | ✅ breadcrumb-item loop |
| Ellipsis collapsing | ✅ true (5+ items) or custom [start, end] | ❌ manual ellipsis item | ✅ ellipsis (4+ count) | ❌ manual |
| Link vs. current page | ✅ to/href → Link; trailing → aria-current page | ✅ separate BreadcrumbLink/BreadcrumbPage | ✅ BreadcrumbItem last = current | ✅ last item auto current |
| Click event with item data | ✅ click(item); disabled suppressed | ❌ native link only | ✅ onClick(route) | ✅ select event |
| Disabled items | ✅ disabled on item data | — | ✅ | — |
Localized aria-label | ✅ locale registry | hard-coded | itemRender only | — |
| Region-level props forwarding | ✅ 6 props groups | asChild per part | itemRender | separator slot |
| Customization slots | ✅ 8 typed slots | ✅ 5 parts + separator slot | itemRender | ✅ separator / title slot |
| Size scaling | ✅ xs…2xl | ✅ fixed | ✅ size | — |
Runtime considerations
- Ellipsis index math —
getEllipsisRangereturnsnullbelow 5 items;[1, len-2]fortrue; user ranges are normalized (start 0 → 1,end length → length - 1) to always keep the first and last item visible. - Ellipsis placement — the collapsed ellipsis is rendered at the new-array index matching
start, i.e. directly before the first post-collapse item; a separator follows the ellipsis. - Disabled click suppression —
handleItemClickignores items withdisabled: true, so theclickevent never carries a disabled item (link clicks are also blocked by the Link primitive). - Link routing —
BreadcrumbLinkextends the Link primitive, soto(router-link) andhref/external(anchor) both work;targetis honored. - Current page semantics — the last item without
to/hrefrenders asBreadcrumbPage(role="link"+aria-disabled="true"+aria-current="page"), so AT users know it is not a navigable link. - Locale fallback — the
navaria-labelcomes fromuseLocaleMessages; missing locale keys fall back to the default English bundle.
FAQ
When does the ellipsis appear?
With ellipsis: true, the ellipsis renders only when there are 5 or more items; the first and last items always stay visible and the middle ones are collapsed. Use ellipsis: [start, end] to pick exactly which range collapses (both endpoints are normalized to keep the edges visible).
How do I make an item a link vs. the current page?
An item with to (router) or href/external (anchor) renders as a link. The trailing item without a destination renders as the current page with aria-current="page". To force a non-last item to be a plain label, omit to/href on it.
Why doesn’t clicking a disabled item emit anything?
Disabled items are intentionally inert: the link is disabled by the Link primitive and the compact component suppresses the click event for disabled: true items, matching the expected breadcrumb behavior.
Can I customize the separator?
Yes — use the separator slot. Each separator (including the one after the ellipsis) renders your content. For per-region styling, pass separatorProps or the ui recipe classes.
What scoped props do the item slots receive?
item-leading, item-link, item-label, item-trailing, and the default slot receive { item, index }; the ellipsis slot receives { ellipsisItems }. The UI wrapper forwards these unchanged to your custom slot content.
Is the breadcrumb accessible?
Yes — the root is a nav with a localized aria-label, the list is an ol, separators and the ellipsis are hidden from assistive technology, and the current page is announced via aria-current="page".
Can I build a fully custom breadcrumb?
Yes — compose BreadcrumbRoot / BreadcrumbList / BreadcrumbItem / BreadcrumbLink / BreadcrumbPage / BreadcrumbSeparator / BreadcrumbEllipsis from @vean/aria/breadcrumb and inject styles via provideBreadcrumbUi (or SBreadcrumb’s ui prop).