Copied into your project as .primitiv-breadcrumb — you own the file afterwards, so upgrades are opt-in.
Headless mode installs the npm package instead: @primitiv-ui/react
Anatomy
Breadcrumb is the <nav> landmark (label it if a page has more than one). Inside, a Breadcrumb.List is the <ol>, and each Breadcrumb.Item an <li>. Ancestor items hold a Breadcrumb.Link; the last holds a Breadcrumb.Page — a <span> with aria-current="page", deliberately not a link, since you can't navigate to where you already are. You place a Breadcrumb.Separator (default /) between items yourself; it is aria-hidden, so it never clutters the announced trail. Breadcrumb.Ellipsis stands in for a collapsed run — see breadcrumb-overflow for the interactive version.
Generated from source — headless rows from each *Props type’s JSDoc, styled rows from contract.json. Never hand-maintained.
Breadcrumb.Root
Extends HTMLElement — every native attribute of that element is accepted and forwarded.
Prop
Type
Default
From
Description
size
"xs" | "sm" | "md" | "lg" | "xl"
md
styled
Control size; data-density scales each size further.
Breadcrumb.List
Extends HTMLOListElement — every native attribute of that element is accepted and forwarded.
No props of its own.
Breadcrumb.Item
Extends HTMLLIElement — every native attribute of that element is accepted and forwarded.
No props of its own.
Breadcrumb.Link
Extends HTMLAnchorElement — every native attribute of that element is accepted and forwarded.
Prop
Type
Default
From
Description
asChild
boolean
false
headless
Renders the child element instead of a native <a>, merging all of
Breadcrumb.Link's props — href, event handlers, className,
ref — onto it via Slot. Use for routing-library link
components (e.g. React Router's <Link>) that need breadcrumb
semantics. See the asChild example on BreadcrumbLink.
Breadcrumb.Page
Extends HTMLSpanElement — every native attribute of that element is accepted and forwarded.
No props of its own.
Breadcrumb.Separator
Extends HTMLLIElement — every native attribute of that element is accepted and forwarded.
No props of its own.
Breadcrumb.Ellipsis
Extends HTMLSpanElement — every native attribute of that element is accepted and forwarded.
Prop
Type
Default
From
Description
asChild
boolean
false
headless
Renders the child element instead of a native <span>, merging all of
Breadcrumb.Ellipsis's props — role, aria-hidden, className,
ref — onto it via Slot. See the asChild example on
BreadcrumbEllipsis.
Styling contract
10 CSS custom properties on .primitiv-breadcrumb — mode-agnostic. These names are the stable surface; the values are not.
Emitted automatically by the headless primitive — style against these rather than adding your own state classes. Grouped by the part that emits them, since most are emitted by more than one.
BreadcrumbPage
className:.primitiv-breadcrumb__page
Attribute
Value
When
aria-current
page
always
Breadcrumb.Page
Attribute
Value
When
aria-current
page
always
Accessibility
It's a <nav> landmark.Breadcrumb renders <nav>; if a page has more than one navigation landmark, give it a label (aria-label="Breadcrumb") so a screen reader can tell them apart.
The current page is a Breadcrumb.Page, not a link. It is a <span> with aria-current="page", which is how assistive technology announces “you are here”. Making the last crumb a link that points at the current URL is the common mistake — you can't navigate to where you already are.
Separators are decorative and hidden.Breadcrumb.Separator is role="presentation" / aria-hidden, so the trail is announced as a clean list of pages without “slash” between each. Whatever glyph you pass stays hidden — no extra ARIA needed.
The list is ordered.Breadcrumb.List is an <ol>, because a trail has a meaningful sequence (root → current); assistive technology conveys the order and position from the real list markup.
Collapsed crumbs must stay reachable. A static Breadcrumb.Ellipsis hides pages from sight and from the keyboard. If the hidden crumbs need to be navigable, use BreadcrumbOverflow, whose ellipsis opens a real menu, rather than dropping them behind a bare glyph.
Examples
Every example below reacts to the density control. Currently showing Styled mode.
A breadcrumb trail
The trail: a <nav> around an <ol> of items. Every step but the last is a Breadcrumb.Link; the last is a Breadcrumb.Page, which is not a link and carries aria-current="page" — the reader is already there. Put a Breadcrumb.Separator between items; it defaults to / and is aria-hidden, so assistive technology hears “Home, Components, Disclosure, Breadcrumb”, not the slashes.
Breadcrumb.Separator defaults to a / glyph; pass children to replace it — a chevron is the common alternative. It stays aria-hidden whatever you put in it, so a decorative icon needs no extra ARIA. Keep it consistent across the whole trail.
A deep trail can collapse its middle behind a Breadcrumb.Ellipsis — a presentational … in place of the hidden crumbs. This one is static: it just shows the ellipsis. For an ellipsis that actually opens a menu of the hidden pages (and decides how many to keep at each end), reach for BreadcrumbOverflow, which composes this with a Dropdown.
Breadcrumb.Link is a real <a> by default — right for plain hrefs. With a routing library, use asChild to merge the link styling onto your router's own <Link>, so navigation stays client-side without a full reload while the crumb still reads as a link. The current page stays a Breadcrumb.Page, never a router link.
Five sizes, each rescaling again with the nearest data-density ancestor. A breadcrumb usually wants to be quiet — xs/sm under a page title — so the smaller end of the ramp is the common choice.