# Breadcrumb (/ui/components/react/breadcrumb)



<Playground component="breadcrumb" />

## Usage [#usage]

```tsx
import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
  BreadcrumbEllipsis,
} from '@appica/ui-react/breadcrumb'
```

```tsx
<Breadcrumb>
  <BreadcrumbList>
    <BreadcrumbItem>
      <BreadcrumbLink href="/">Home</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbLink href="/ui/components">Components</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbLink active>Breadcrumb</BreadcrumbLink>
    </BreadcrumbItem>
  </BreadcrumbList>
</Breadcrumb>
```

`Breadcrumb` is a small set of semantic primitives — there's no hidden state, so you lay the trail out yourself. Every part lives under `@appica/ui-react/breadcrumb`:

* **`Breadcrumb`** — the `<nav aria-label="breadcrumb">` landmark that wraps the trail.
* **`BreadcrumbList`** — the ordered list (`<ol>`) of crumbs; handles wrapping and spacing.
* **`BreadcrumbItem`** — one `<li>`, holding a link (or a collapsed menu).
* **`BreadcrumbLink`** — a crumb. By default it renders an `<a>`; mark the current page with `active` and it becomes a non-interactive `<span>` with `aria-current="page"`.
* **`BreadcrumbSeparator`** — the divider between crumbs (a chevron by default; pass `children` to override).
* **`BreadcrumbEllipsis`** — a "…" placeholder for crumbs collapsed out of a long trail.

`BreadcrumbLink` uses Base UI's [`useRender`](https://base-ui.com/react/utils/use-render), so you can project it onto your router's link with `render` — e.g. a Next.js [`Link`](https://nextjs.org/docs/app/api-reference/components/link) — without losing the styling or the active state.

Reach for a `Breadcrumb` to show **where the current page sits** in a hierarchy. For switching between sibling views, use [`Navigation`](/ui/components/react/navigation) or [`Tabs`](/ui/components/react/tabs); for a menu of links opened from a button, use a [`Dropdown Menu`](/ui/components/react/dropdown-menu).

## Examples [#examples]

### Basic [#basic]

A trail of links ending in the current page. Give every link before the last an `href`; mark the final crumb `active` so it renders as plain, non-focusable text with `aria-current="page"`.

```tsx
import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
} from '@appica/ui-react/breadcrumb'

export default function BreadcrumbBasic() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#!">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#!">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink active>Breadcrumb</BreadcrumbLink>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}
```

### With icons [#with-icons]

Drop an icon straight inside a `BreadcrumbLink` — it's sized and spaced automatically next to the label. A leading [icon](/ui/icons) on the Home crumb is a common space-saver.

```tsx
import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
} from '@appica/ui-react/breadcrumb'
import { Home, Folder, FileText } from '@appica/icons-react'

export default function BreadcrumbIcons() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#!">
            <Home />
            Home
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#!">
            <Folder />
            Projects
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink active>
            <FileText />
            Roadmap
          </BreadcrumbLink>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}
```

### Custom separators [#custom-separators]

`BreadcrumbSeparator` renders a chevron by default. Pass it `children` to swap in anything — a slash, a dot, or your own [icon](/ui/icons). The separator is decorative (`aria-hidden`), so it's skipped by screen readers.

```tsx
import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
} from '@appica/ui-react/breadcrumb'

export default function BreadcrumbSeparators() {
  return (
    <div className="flex flex-col gap-5">
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink href="#!">Home</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator>/</BreadcrumbSeparator>
          <BreadcrumbItem>
            <BreadcrumbLink href="#!">Docs</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator>/</BreadcrumbSeparator>
          <BreadcrumbItem>
            <BreadcrumbLink active>Breadcrumb</BreadcrumbLink>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>

      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink href="#!">Home</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator>
            <span className="bg-foreground-muted size-0.75 rounded-full" />
          </BreadcrumbSeparator>
          <BreadcrumbItem>
            <BreadcrumbLink href="#!">Docs</BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator>
            <span className="bg-foreground-muted size-0.75 rounded-full" />
          </BreadcrumbSeparator>
          <BreadcrumbItem>
            <BreadcrumbLink active>Breadcrumb</BreadcrumbLink>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>
    </div>
  )
}
```

### Soft badges [#soft-badges]

Project each `BreadcrumbLink` onto a soft [`Badge`](/ui/components/react/badge) with `render` for a pill-style trail. The Badge's `soft` variant has built-in breadcrumb support — idle crumbs render muted like a plain link, brighten on hover, and the `active` crumb gains a bordered, filled pill. Project the Badge onto an `<a>` (`render={<a />}`) so the hover background animates.

```tsx
import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
} from '@appica/ui-react/breadcrumb'
import { Badge } from '@appica/ui-react/badge'
import { Home, Components } from '@appica/icons-react'

export default function BreadcrumbBadges() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#!" render={<Badge variant="soft" render={<a />} />}>
            <Home data-icon="start" />
            Home
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#!" render={<Badge variant="soft" render={<a />} />}>
            <Components data-icon="start" />
            Library
          </BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink active render={<Badge variant="soft" />}>
            <Components data-icon="start" />
            Component
          </BreadcrumbLink>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}
```

### Collapsed trail [#collapsed-trail]

When a trail is too long, collapse the middle crumbs behind a menu. Wrap a [`Dropdown Menu`](/ui/components/react/dropdown-menu) in the `BreadcrumbItem`, project the trigger onto the `BreadcrumbEllipsis`, and list the hidden pages as `DropdownMenuLinkItem`s. The ellipsis carries an `sr-only` "More" label, so the trigger stays named for assistive tech.

```tsx
import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
  BreadcrumbEllipsis,
} from '@appica/ui-react/breadcrumb'
import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuLinkItem,
} from '@appica/ui-react/dropdown-menu'

export default function BreadcrumbCollapsed() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="#!">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <DropdownMenu>
            <DropdownMenuTrigger className="text-foreground-muted hover:text-foreground-intense outline-ring hover:bg-background-muted data-popup-open:bg-background-muted data-popup-open:text-foreground-intense rounded-2xs flex size-6 items-center justify-center transition">
              <BreadcrumbEllipsis />
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start">
              <DropdownMenuLinkItem href="#!">Documentation</DropdownMenuLinkItem>
              <DropdownMenuLinkItem href="#!">Components</DropdownMenuLinkItem>
              <DropdownMenuLinkItem href="#!">Themes</DropdownMenuLinkItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="#!">Breadcrumb</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink active>Collapsed</BreadcrumbLink>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}
```

### Router links [#router-links]

For client-side routing, project a `BreadcrumbLink` onto your framework's link via `render` — here a Next.js [`Link`](https://nextjs.org/docs/app/api-reference/components/link). The crumb keeps its styling and `aria-current` handling while the router owns navigation.

```tsx
import Link from 'next/link'
import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbSeparator,
} from '@appica/ui-react/breadcrumb'

export default function BreadcrumbLinks() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink render={<Link href="/ui/components/react/breadcrumb" />}>Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink render={<Link href="/ui/components/react/breadcrumb" />}>Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink active>Breadcrumb</BreadcrumbLink>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}
```

## RTL [#rtl]

Every Appica UI component supports right-to-left layouts out of the box. Set the `dir` attribute on a container (commonly your `<html>` element) so CSS logical properties resolve correctly, and wrap your tree in `DirectionProvider` so direction-aware behavior follows the same direction.

```tsx
import { DirectionProvider } from '@appica/ui-react/providers/direction-provider'

export default function RootLayout({ children }) {
  return (
    <html lang="ar" dir="rtl">
      <body>
        <DirectionProvider dir="rtl">{children}</DirectionProvider>
      </body>
    </html>
  )
}
```

The trail flows from the right and the default chevron separator mirrors to point the other way. For setup details and caveats, see the [RTL guide](/ui/docs/react/rtl).

<RtlPreview component="breadcrumb" />

## API reference [#api-reference]

Breadcrumb is a set of styled HTML elements. Each part forwards every remaining prop to its underlying element (`nav`, `ol`, `li`, `a`, `span`), so any native attribute works here — the tables below list the Appica additions and the most common props.

### Breadcrumb [#breadcrumb]

The navigation landmark. Renders a `<nav aria-label="breadcrumb">`.

| Prop        | Type        | Default | Description                                 |
| ----------- | ----------- | ------- | ------------------------------------------- |
| `children`  | `ReactNode` | —       | A single `BreadcrumbList`.                  |
| `className` | `string`    | —       | Extra classes, merged via `tailwind-merge`. |

### BreadcrumbList [#breadcrumblist]

The ordered list of crumbs. Renders an `<ol>` that wraps and spaces its items.

| Prop        | Type        | Default | Description                                   |
| ----------- | ----------- | ------- | --------------------------------------------- |
| `children`  | `ReactNode` | —       | `BreadcrumbItem`s and `BreadcrumbSeparator`s. |
| `className` | `string`    | —       | Extra classes, merged via `tailwind-merge`.   |

### BreadcrumbItem [#breadcrumbitem]

One crumb's `<li>` wrapper.

| Prop        | Type        | Default | Description                                 |
| ----------- | ----------- | ------- | ------------------------------------------- |
| `children`  | `ReactNode` | —       | A `BreadcrumbLink`, ellipsis, or menu.      |
| `className` | `string`    | —       | Extra classes, merged via `tailwind-merge`. |

### BreadcrumbLink [#breadcrumblink]

A crumb link. Built on Base UI's [`useRender`](https://base-ui.com/react/utils/use-render); renders an `<a>` unless `active` (then a `<span>`), or use `render` to project it onto another element.

| Prop        | <ColMinWidth width="220">Type</ColMinWidth>                 | Default | Description                                                                           |
| ----------- | ----------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------- |
| `active`    | `boolean`                                                   | `false` | Mark the current page. Renders a non-interactive `<span>` with `aria-current="page"`. |
| `disabled`  | `boolean`                                                   | `false` | Make the link non-interactive and dimmed.                                             |
| `render`    | <Code>ReactElement \| (props, state) => ReactElement</Code> | —       | Render as your own element (e.g. a router `Link`).                                    |
| `href`      | `string`                                                    | —       | Navigation target (when rendered as an `<a>`).                                        |
| `className` | `string`                                                    | —       | Extra classes, merged via `tailwind-merge`.                                           |

### BreadcrumbSeparator [#breadcrumbseparator]

The divider between crumbs. Decorative (`aria-hidden`); renders a chevron unless you pass `children`.

| Prop        | Type        | Default      | Description                                        |
| ----------- | ----------- | ------------ | -------------------------------------------------- |
| `children`  | `ReactNode` | chevron icon | Override the separator with your own text or icon. |
| `className` | `string`    | —            | Extra classes, merged via `tailwind-merge`.        |

### BreadcrumbEllipsis [#breadcrumbellipsis]

A "…" placeholder for collapsed crumbs. Decorative, with an `sr-only` "More" label.

| Prop        | Type        | Default       | Description                                 |
| ----------- | ----------- | ------------- | ------------------------------------------- |
| `children`  | `ReactNode` | ellipsis dots | Override the placeholder mark.              |
| `className` | `string`    | —             | Extra classes, merged via `tailwind-merge`. |

## Accessibility [#accessibility]

* `Breadcrumb` renders a `<nav>` with `aria-label="breadcrumb"`, so it's exposed as a named navigation landmark.
* The current page (`active`) is a `<span>` with `aria-current="page"` — not a link — so it isn't announced as clickable.
* Separators and the ellipsis are `aria-hidden`/`role="presentation"`; the ellipsis keeps an `sr-only` "More" label for the collapse trigger.
* `disabled` links set `aria-disabled` and drop out of the tab order.
* Crumbs are keyboard-focusable links by default and inherit the page's focus-ring styling.
