{
  "title": "Breadcrumb",
  "description": "Cross-platform breadcrumb trail with width-aware collapse, sibling menus, JSON-LD schema, and an agent-friendly items API.",
  "url": "/docs/components/breadcrumb",
  "since": "0.0.6",
  "tags": [
    "navigation"
  ],
  "platform": "both",
  "source": "---\ntitle: Breadcrumb\ndescription: Cross-platform breadcrumb trail with width-aware collapse, sibling menus, JSON-LD schema, and an agent-friendly items API.\nsince: 0.0.6\ntags: [navigation]\nplatform: both\ncategory: navigation\n---\n\nimport { BundleSize } from '@/components/bundle-size';\nimport { Preview } from '@/components/preview';\nimport { PropsTable } from '@/components/props-table';\n\n<BundleSize component=\"Breadcrumb\" />\n\n## At a glance\n\n- **Two equivalent APIs**: `<Breadcrumb items={[…]} />` for terse, agent-friendly markup and a compound `Breadcrumb.List` / `Breadcrumb.Item` / `Breadcrumb.Link` / `Breadcrumb.Page` form for full JSX control.\n- **Width-aware collapse on web AND native** via `onLayout` (RN-Web routes through `ResizeObserver`; native uses its own layout system). Middle items fold into an interactive ellipsis when the container can't fit the trail. **On by default** — pass `collapseOnOverflow={false}` to opt out.\n- **Count-based collapse** (`maxItems`, `itemsBeforeCollapse`, `itemsAfterCollapse`) as a deterministic ceiling above width fit.\n- **`expandBehavior`**: `inline` (web default) folds the trail back open; `menu` (native default) opens a popover with the hidden items; `scroll` falls back to a horizontal scroller for IDE-style file paths; `none` is purely visual.\n- **Per-item icons**, **sibling menus** (the VSCode/file-path pattern), label truncation, loading skeletons, and RTL chevron flip via `dir=\"rtl\"`.\n- **JSON-LD `BreadcrumbList`** structured data is injected automatically on web for SEO + LLM ingest. SSR consumers should call the exported `getBreadcrumbJsonLd(items)` helper from their framework's metadata API instead.\n- **Auto `aria-current=\"page\"`** on the last item (or any item flagged `current`), with a visually-hidden \"Current page:\" prefix for screen readers. The wrapper is a real `<nav>` landmark with a localized `aria-label`.\n- i18n hooks: `breadcrumb.ariaLabel`, `breadcrumb.expandLabel`, `breadcrumb.ellipsisLabel`, `breadcrumb.currentPageLabel`, `breadcrumb.siblingMenuLabel`.\n\n## Preview\n\n<Preview name=\"breadcrumb-basic\" />\n\n## Custom separators\n\nThe default is a chevron that auto-flips for RTL. Pass any string, ReactNode, or `(ctx) => ReactNode` to customize.\n\n<Preview name=\"breadcrumb-separators\" />\n\n## With icons\n\nAdd a leading icon per item via the `icon` prop — sized to the line height. Any icon component with the shape `({ size?: number; color?: string }) => ReactNode` works (lucide, custom SVG, your own icon set).\n\n<Preview name=\"breadcrumb-icons\" />\n\n## Count-based collapse\n\nSet `maxItems` to fold the middle of the trail into an ellipsis. Click the ellipsis to expand inline (default on web).\n\n<Preview name=\"breadcrumb-collapse\" />\n\n## Width-based collapse\n\nWidth-based collapse is **on by default**. The library renders a hidden measurement copy of every item via `onLayout`, then shows only the items that fit the container's available width — middle items fold into the ellipsis. Resize the container in the demo below to see it in action. Pass `collapseOnOverflow={false}` to opt out and let the row grow to its natural width (consider only when the parent provides its own scroll/clip handling).\n\n<Preview name=\"breadcrumb-width-collapse\" />\n\n## Sibling menus (VSCode-style)\n\nPass a `siblings` array on any item to add a chevron toggle that opens a popover menu of sibling pages — useful for file paths or any breadcrumb where the user might want to jump laterally.\n\n<Preview name=\"breadcrumb-sibling-menu\" />\n\n## Compound API\n\nFor full JSX control, use the compound subcomponents. Separators auto-insert between consecutive `Breadcrumb.Item`s unless you place your own.\n\n<Preview name=\"breadcrumb-compound\" />\n\n## SEO + LLM ingest\n\nThe component injects a `BreadcrumbList` JSON-LD document into `<head>` on the client when `items` is provided. For SSR-time emission (recommended for crawler reliability), use the helper:\n\n```tsx\nimport { getBreadcrumbJsonLd } from '@nori-ui/core';\n\n// Next.js App Router metadata\nexport async function generateMetadata() {\n    return {\n        other: {\n            'application/ld+json': getBreadcrumbJsonLd([\n                { label: 'Home', href: 'https://example.com/' },\n                { label: 'Docs', href: 'https://example.com/docs' },\n                { label: 'Breadcrumb' },\n            ]),\n        },\n    };\n}\n```\n\nPass `schemaOrg={false}` on the component to opt out of the client-side injection if you're already emitting JSON-LD via your metadata pipeline.\n\n## Localization — `ariaLabel`, `currentPageLabel`, `ellipsisLabel`, `expandLabel`, `siblingMenuLabel`\n\nEvery user-visible string is overridable per-instance. Defaults come\nfrom the active i18n dictionary (`breadcrumb.*` keys); pass props to\noverride one Breadcrumb without touching the global translations.\n\n| Prop                  | Purpose                                              |\n|-----------------------|------------------------------------------------------|\n| `ariaLabel`           | `<nav>` landmark label                               |\n| `currentPageLabel`    | Visually-hidden prefix on the current item (\"Current page:\") |\n| `ellipsisLabel`       | Accessible name for the collapsed-middle ellipsis    |\n| `expandLabel`         | Tooltip / aria-label on the click-to-expand affordance |\n| `siblingMenuLabel`    | Accessible name for the sibling-pages chevron toggle |\n\n```tsx\n<Breadcrumb ariaLabel=\"Site navigation\" items={[…]} />\n```\n\n## `separator`\n\nCustomize the per-item separator. Accepts a string, a ReactNode, or a\nfunction `(ctx) => ReactNode` that gets the surrounding item context.\nDefault is a chevron that flips for `dir=\"rtl\"`.\n\n```tsx\n<Breadcrumb separator=\"/\" items={…} />\n<Breadcrumb separator={<SlashIcon />} items={…} />\n```\n\n## `maxLabelLength`\n\nCap individual item labels at N characters; the component truncates\nwith an ellipsis and exposes the full label on hover (web `title`)\nand to assistive tech. Useful for file-path breadcrumbs where one\nsegment can be unboundedly long.\n\n```tsx\n<Breadcrumb maxLabelLength={24} items={…} />\n```\n\n## `dir`\n\n`rtl` flips the chevron direction *and* the DOM order of the trail so\nthe start of the path sits on the right.\n\n```tsx\n<Breadcrumb dir=\"rtl\" items={…} />\n```\n\n## Props\n\n### Breadcrumb\n\n<PropsTable component=\"Breadcrumb\" />\n\n### Breadcrumb.List\n\n<PropsTable component=\"BreadcrumbList\" />\n\n### Breadcrumb.Item\n\n<PropsTable component=\"BreadcrumbItem\" />\n\n### Breadcrumb.Link\n\n<PropsTable component=\"BreadcrumbLink\" />\n\n### Breadcrumb.Page\n\n<PropsTable component=\"BreadcrumbPage\" />\n\n### Breadcrumb.Separator\n\n<PropsTable component=\"BreadcrumbSeparator\" />\n\n### Breadcrumb.Ellipsis\n\n<PropsTable component=\"BreadcrumbEllipsis\" />\n"
}
