Breadcrumb
Displays the path to the current resource using a hierarchy of links.
Installation
Copy and paste the following code into your project.
import { Slot } from '@radix-ui/react-slot';
import clsx from 'clsx';
import { ChevronRight, MoreHorizontal } from 'lucide-react';
import { ComponentProps, ComponentPropsWithoutRef, ReactNode, forwardRef } from 'react';
import styles from './styles.module.scss';
const Breadcrumb = forwardRef<
HTMLElement,
ComponentPropsWithoutRef<'nav'> & {
separator?: ReactNode;
}
>(({ ...props }, ref) => <nav ref={ref} aria-label='breadcrumb' {...props} />);
Breadcrumb.displayName = 'Breadcrumb';
const BreadcrumbList = forwardRef<HTMLOListElement, ComponentPropsWithoutRef<'ol'>>(({ className, ...props }, ref) => (
<ol ref={ref} className={clsx(styles.breadcrumb__list, className)} {...props} />
));
BreadcrumbList.displayName = 'BreadcrumbList';
const BreadcrumbItem = forwardRef<HTMLLIElement, ComponentPropsWithoutRef<'li'>>(({ className, ...props }, ref) => (
<li ref={ref} className={clsx(styles.breadcrumb__item, className)} {...props} />
));
BreadcrumbItem.displayName = 'BreadcrumbItem';
const BreadcrumbLink = forwardRef<
HTMLAnchorElement,
ComponentPropsWithoutRef<'a'> & {
asChild?: boolean;
}
>(({ asChild, className, ...props }, ref) => {
const Comp = asChild ? Slot : 'a';
return <Comp ref={ref} className={clsx(styles.breadcrumb__link, className)} {...props} />;
});
BreadcrumbLink.displayName = 'BreadcrumbLink';
const BreadcrumbPage = forwardRef<HTMLSpanElement, ComponentPropsWithoutRef<'span'>>(({ className, ...props }, ref) => (
<span
ref={ref}
role='link'
aria-disabled='true'
aria-current='page'
className={clsx(styles.breadcrumb__page, className)}
{...props}
/>
));
BreadcrumbPage.displayName = 'BreadcrumbPage';
const BreadcrumbSeparator = ({ children, className, ...props }: ComponentProps<'span'>) => (
<span role='presentation' aria-hidden='true' className={clsx(styles.breadcrumb__separator, className)} {...props}>
{children ?? <ChevronRight />}
</span>
);
BreadcrumbSeparator.displayName = 'BreadcrumbSeparator';
const BreadcrumbEllipsis = ({ className, ...props }: ComponentProps<'span'>) => (
<span role='presentation' aria-hidden='true' className={clsx(styles.breadcrumb__ellipsis, className)} {...props}>
<MoreHorizontal className={styles.breadcrumb__ellipsis__icon} />
<span className={styles.sr_only}>More</span>
</span>
);
BreadcrumbEllipsis.displayName = 'BreadcrumbElipssis';
export {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
};Update the import paths to match your project setup.
Usage
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/components/ui/breadcrumb';<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 { Slash } from "lucide-react"
...
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>Dropdown
You can compose <BreadcrumbItem /> with a <DropdownMenu /> to create a dropdown in the breadcrumb.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
...
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger className="flex items-center gap-1">
Components
<ChevronDownIcon />
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem>Documentation</DropdownMenuItem>
<DropdownMenuItem>Themes</DropdownMenuItem>
<DropdownMenuItem>GitHub</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>Collapsed
We provide a <BreadcrumbEllipsis /> component to show a collapsed state when the breadcrumb is too long.
import { BreadcrumbEllipsis } from "@/components/ui/breadcrumb"
...
<Breadcrumb>
<BreadcrumbList>
{/* ... */}
<BreadcrumbItem>
<BreadcrumbEllipsis />
</BreadcrumbItem>
{/* ... */}
</BreadcrumbList>
</Breadcrumb>Link component
To use a custom link component from your routing library, you can use the asChild prop on <BreadcrumbLink />.
import { Link } from "next/link"
...
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="/">Home</Link>
</BreadcrumbLink>
</BreadcrumbItem>
{/* ... */}
</BreadcrumbList>
</Breadcrumb>Responsive
Here's an example of a responsive breadcrumb that composes <BreadcrumbItem /> with <BreadcrumbEllipsis />, <DropdownMenu />, and <Drawer />.
It displays a dropdown on desktop and a drawer on mobile.