Breadcrumb Bar
A page-header strip — the wiki / technical-docs "double-rule" navigation pattern. Wraps the crumb trail with optional hairline rules above and below, plus an optional small-caps eyebrow label, so you drop in one component instead of composing the surround yourself.
Reach for the simpler Breadcrumb compound when you want a bare trail without the wrapping chrome — BreadcrumbBar is the richer "page header" sibling.
Customize
Surround
both
Content
Installation
npx shadcn@latest add https://craftbits.dev/r/breadcrumb-bar.jsonUsage
Pass an ordered list of items. The last entry is treated as the current page — omit its href so it renders as a non-link <span> with aria-current="page".
import { BreadcrumbBar } from "@craft-bits/core";
<BreadcrumbBar
eyebrow="Documentation"
items={[
{ label: "Docs", href: "/docs" },
{ label: "Components", href: "/docs/components" },
{ label: "Buttons", href: "/docs/components/buttons" },
{ label: "Button" },
]}
/>Swap the default slash separator for a chevron (or any node):
<BreadcrumbBar separator=">" items={[/* ... */]} />Control which hairline rules wrap the bar — top, bottom, both (default), or none:
<BreadcrumbBar rule="bottom" items={[/* ... */]} />Understanding the component
- Self-contained header strip. Unlike the bare
Breadcrumbcompound,BreadcrumbBarships the wrapping structure — the top and bottom hairline rules and the small-caps eyebrow above — so it works as a drop-in page header. One component, one prop surface, one render. - Eyebrow + trail composition. The optional
eyebrowrenders above the crumb row in the canonical small-caps mono treatment — uppercase, mono, low-opacity, tracked. It supplies the section context ("Documentation", "Lessons", "Reference") that the trail itself can stay terse about. - Items array, last is current. The trail accepts a flat array of label / href pairs so call-sites stay terse. Any entry with an
hrefrenders as an<a>; the final entry is the current page and renders as a<span>witharia-current="page", drawn in the accent color so the eye lands on it. - Configurable rule placement.
rule="both"is the default — the wiki / docs pattern. Switch totop,bottom, ornonefor tighter contexts (top of a card, bottom of a hero, no rule at all). - Configurable separator. Defaults to a slash for a wiki vibe. Pass a chevron, an icon, anything. Separators carry
aria-hidden="true"androle="presentation"because the<ol>already conveys order to assistive tech. - Semantic ordered list. The trail is an
<ol>inside a<nav aria-label="Breadcrumb">. Screen readers announce position ("item 2 of 4") because the sequence is meaningful.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | { label: ReactNode; href?: string }[] | required | Ordered trail. Last entry is the current page; omit its href. |
eyebrow | ReactNode | — | Small-caps label above the trail. Hidden when omitted. |
rule | 'top' | 'bottom' | 'both' | 'none' | 'both' | Which hairline rules wrap the bar. |
separator | ReactNode | '/' | Glyph between two crumbs. |
className | string | — | Merged onto the root <nav> via cn(). |
...rest | HTMLAttributes<HTMLElement> (minus title) | — | Any other <nav> prop. |
Accessibility
- Renders a
<nav aria-label="Breadcrumb">landmark with an<ol>inside — the canonical W3C ARIA pattern. - The current crumb carries
aria-current="page"so assistive tech announces it as the current location. - Separators are
aria-hidden="true"androle="presentation"— the<ol>already conveys order; reading "slash" between every crumb would just add noise. - Each link gets a
focus-visible:ring keyed to--cb-accentand offset from--cb-bg, so keyboard users always see where they are on every theme surface. - Color contrast in the default theme: link text uses
--cb-fg-muted, the current page uses--cb-accent, the eyebrow uses--cb-fg-subtle— all pass WCAG AA against--cb-bg.
Credits
- Extracted from:
terminal-dreams(src/components/retro/BreadcrumbBar.tsx). The original was a thin wrapper around a project-localBreadcrumbwith a hardcoded bottom border and aThemeTogglepinned to the right. craft-bits drops the theme-toggle slot (it belongs in app chrome, not the breadcrumb), turns the single bottom border into a configurableruleprop, and adds the optionaleyebrowso the bar reads as the full wiki-style page header out of the box. The simpler bare-trail primitive ships as the siblingBreadcrumbcomponent.