shadcn-remix
GitHub

Breadcrumb

Displays the path to the current resource using a hierarchy of links.

import { css } from 'remix/component'

import {
  Breadcrumb,
  BreadcrumbEllipsis,
  BreadcrumbItem,
import { css } from 'remix/component'

import {
  Breadcrumb,
  BreadcrumbEllipsis,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '#app/ui/breadcrumb.tsx'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '#app/ui/dropdown-menu.tsx'

const triggerStyles = css({ display: 'flex', alignItems: 'center', gap: '0.25rem' })
const ellipsisStyles = css({ width: '1rem', height: '1rem' })
const srOnly = css({
  position: 'absolute',
  width: '1px',
  height: '1px',
  padding: 0,
  margin: '-1px',
  overflow: 'hidden',
  clip: 'rect(0, 0, 0, 0)',
  whiteSpace: 'nowrap',
  borderWidth: 0,
})

export function BreadcrumbDemo() {
  return () => (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="/">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <DropdownMenu>
            <DropdownMenuTrigger mix={triggerStyles}>
              <BreadcrumbEllipsis mix={ellipsisStyles} />
              <span mix={srOnly}>Toggle menu</span>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start">
              <DropdownMenuItem>Documentation</DropdownMenuItem>
              <DropdownMenuItem>Themes</DropdownMenuItem>
              <DropdownMenuItem>GitHub</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="/docs/components">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Installation

$ pnpm dlx shadcn@latest add https://www.shadcn-remix.com/r/breadcrumb.json

Usage

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '#app/ui/breadcrumb.tsx'
<Breadcrumb>
  <BreadcrumbList>
    <BreadcrumbItem>
      <BreadcrumbLink href="/">Home</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbLink href="/components">Components</BreadcrumbLink>
    </BreadcrumbItem>
    <BreadcrumbSeparator />
    <BreadcrumbItem>
      <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
    </BreadcrumbItem>
  </BreadcrumbList>
</Breadcrumb>

Examples

Custom separator

Use a custom component as children for <BreadcrumbSeparator /> to create a custom separator.

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator as BreadcrumbDivider,
} from '#app/ui/breadcrumb.tsx'
import { SlashIcon } from '#app/ui/icons.tsx'

export function BreadcrumbSeparator() {
  return () => (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="/">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbDivider>
          <SlashIcon />
        </BreadcrumbDivider>
        <BreadcrumbItem>
          <BreadcrumbLink href="/components">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbDivider>
          <SlashIcon />
        </BreadcrumbDivider>
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

You can compose <BreadcrumbItem /> with a <DropdownMenu /> to create a dropdown in the breadcrumb.

import { css } from 'remix/component'

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
import { css } from 'remix/component'

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '#app/ui/breadcrumb.tsx'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '#app/ui/dropdown-menu.tsx'
import { ChevronDownIcon, SlashIcon } from '#app/ui/icons.tsx'

const triggerStyles = css({
  display: 'flex',
  alignItems: 'center',
  gap: '0.25rem',
  '& svg': { pointerEvents: 'none', flexShrink: 0 },
  '& svg:not([class*="size-"])': { width: '0.875rem', height: '0.875rem' },
})

export function BreadcrumbDropdown() {
  return () => (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="/">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator>
          <SlashIcon />
        </BreadcrumbSeparator>
        <BreadcrumbItem>
          <DropdownMenu>
            <DropdownMenuTrigger mix={triggerStyles}>
              Components
              <ChevronDownIcon />
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start">
              <DropdownMenuItem>Documentation</DropdownMenuItem>
              <DropdownMenuItem>Themes</DropdownMenuItem>
              <DropdownMenuItem>GitHub</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </BreadcrumbItem>
        <BreadcrumbSeparator>
          <SlashIcon />
        </BreadcrumbSeparator>
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Collapsed

We provide a <BreadcrumbEllipsis /> component to show a collapsed state when the breadcrumb is too long.

import {
  Breadcrumb,
  BreadcrumbEllipsis as BreadcrumbEllipsisIndicator,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
import {
  Breadcrumb,
  BreadcrumbEllipsis as BreadcrumbEllipsisIndicator,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '#app/ui/breadcrumb.tsx'

export function BreadcrumbEllipsis() {
  return () => (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="/">Home</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbEllipsisIndicator />
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="/docs/components">Components</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

BreadcrumbLink is a plain <a>. Pass href and any anchor attributes, or apply its styles to your own element with mix.

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink as BreadcrumbAnchor,
  BreadcrumbList,
  BreadcrumbPage,
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink as BreadcrumbAnchor,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '#app/ui/breadcrumb.tsx'

export function BreadcrumbLink() {
  return () => (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbAnchor href="/">Home</BreadcrumbAnchor>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbAnchor href="/components">Components</BreadcrumbAnchor>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

API Reference

PropTypeDefault
mixMixValue-
PropTypeDefault
mixMixValue-
PropTypeDefault
mixMixValue-

A breadcrumb <a>. Remix has no asChild: links are plain anchors, so pass href (and any other anchor attribute or mixin, e.g. link(...)) directly.

PropTypeDefault
mixMixValue-
PropTypeDefault
mixMixValue-
PropTypeDefault
mixMixValue-
PropTypeDefault
mixMixValue-