rapidUI

Breadcrumb

Hierarchical page trail with separators and an overflow ellipsis.

Installation

pnpm dlx shadcn@latest add https://rdf.dev.360online.com/r/breadcrumb.json

Installs to @/components/ui/breadcrumb.

Manual installation

Install the dependencies:

pnpm add @base-ui/react@^1.8.0 lucide-react@^1.48.0

Copy the source into your project:

components/ui/breadcrumb.tsx
import { mergeProps } from '@base-ui/react/merge-props'
import { useRender } from '@base-ui/react/use-render'
import { ChevronRightIcon, MoreHorizontalIcon } from 'lucide-react'
import type * as React from 'react'
import { cn } from '@/lib/utils'

function Breadcrumb({ className, ...props }: React.ComponentProps<'nav'>) {
	return <nav aria-label="breadcrumb" data-slot="breadcrumb" className={cn(className)} {...props} />
}

function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {
	return (
		<ol
			data-slot="breadcrumb-list"
			className={cn('flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-foreground', className)}
			{...props}
		/>
	)
}

function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {
	return <li data-slot="breadcrumb-item" className={cn('inline-flex items-center gap-1', className)} {...props} />
}

function BreadcrumbLink({ className, render, ...props }: useRender.ComponentProps<'a'>) {
	return useRender({
		defaultTagName: 'a',
		props: mergeProps<'a'>(
			{
				className: cn(
					'text-foreground underline underline-offset-4 transition-colors hover:text-primary focus-visible:rounded-sm focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none',
					className,
				),
			},
			props,
		),
		render,
		state: {
			slot: 'breadcrumb-link',
		},
	})
}

function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
	return (
		<span
			data-slot="breadcrumb-page"
			role="link"
			aria-disabled="true"
			aria-current="page"
			tabIndex={0}
			className={cn(
				'cursor-default font-normal text-primary focus-visible:rounded-sm focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none',
				className,
			)}
			{...props}
		/>
	)
}

function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>) {
	return (
		<li data-slot="breadcrumb-separator" aria-hidden="true" className={cn('[&>svg]:size-3.5', className)} {...props}>
			{children ?? <ChevronRightIcon />}
		</li>
	)
}

function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>) {
	return (
		<span
			data-slot="breadcrumb-ellipsis"
			aria-hidden="true"
			className={cn('flex size-5 items-center justify-center [&>svg]:size-4', className)}
			{...props}
		>
			<MoreHorizontalIcon />
			<span className="sr-only">More</span>
		</span>
	)
}

export {
	Breadcrumb,
	BreadcrumbList,
	BreadcrumbItem,
	BreadcrumbLink,
	BreadcrumbPage,
	BreadcrumbSeparator,
	BreadcrumbEllipsis,
}

A breadcrumb navigation component that helps users understand their current location within a hierarchical structure.

Features

  • Semantic HTML structure using <nav> and <ol> elements
  • Links use the foreground color and shift to the primary color on hover; the current page uses the primary color
  • Customizable separators (defaults to a chevron icon)
  • BreadcrumbEllipsis for collapsed paths, composable with a dropdown menu
  • render on BreadcrumbLink to render your router's link component
  • Screen reader friendly with proper ARIA attributes

Usage

import {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '@/components/ui/breadcrumb'

export default function BreadcrumbDemo() {
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="/">Start</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbLink href="/building-permits">Building permits</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Apply for a building permit</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  )
}

Examples

Default

The path to an e-service on the municipality’s website.

With Ellipsis

Use the BreadcrumbEllipsis component to collapse the middle levels of a deep path, such as a document inside a case.

With Dropdown

Compose BreadcrumbEllipsis or a breadcrumb label with a DropdownMenu to let users jump to collapsed or sibling pages.

Custom Separator

You can customize the separator by providing children to the BreadcrumbSeparator component. Separator icons are sized to size-3.5 automatically.

<BreadcrumbSeparator>
  <SlashIcon />
</BreadcrumbSeparator>

With Icon

Links can contain icons alongside text.

In a Page Header

Place the breadcrumb above the page title, here the header of a case in case management.

Use the render prop on BreadcrumbLink to render a custom link component, such as Next.js Link.

import Link from 'next/link'

<BreadcrumbItem>
  <BreadcrumbLink render={<Link href="/" />}>Start</BreadcrumbLink>
</BreadcrumbItem>

Accessibility

The Breadcrumb component follows WAI-ARIA guidelines for breadcrumb navigation:

  • Uses semantic HTML with <nav> and <ol> elements
  • Includes aria-label="breadcrumb" on the navigation element
  • Current page is marked with aria-current="page"
  • Separators are marked with aria-hidden="true" and role="presentation"
  • The current page (BreadcrumbPage) is not a focusable link; it uses role="link" with aria-disabled="true"
  • Screen reader announcements for the current page and navigation items

Props

The root <nav> element (aria-label="breadcrumb") that wraps the breadcrumb navigation. Accepts all nav props.

The ordered list component that contains the breadcrumb items.

A list item component that wraps individual breadcrumb elements.

An anchor component for clickable breadcrumb items. Accepts all a props plus render to render a custom element (e.g. render={<Link href="/" />}).

A <span> that represents the current page in the breadcrumb trail (aria-current="page").

A list item that renders the separator between breadcrumb items. Renders a chevron by default; pass children to override.

A component that indicates truncated navigation items.