Displays the path to the current resource using a hierarchy of links.
Installation
npx shadcn@latest add @caprice/breadcrumbnpm install @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, type VariantProps } from 'cva';import { twMerge } from 'tailwind-merge';export const { compose, cva, cx: cn,} = defineConfig({ hooks: { onComplete: (className: string) => twMerge(className), },});export type { VariantProps };Copy and paste the following code into your project.
import { mergePropsN, useRender } from '@base-ui/react';import { ChevronRight, MoreHorizontal } from 'lucide-react';import { cn } from '@/lib/utils';/** * A navigation component that displays the user's current location in the site hierarchy. * Renders a `<nav>` element. * * Documentation: [Caprice UI Breadcrumb](https://caprice-ui.com/docs/components/breadcrumb) */export namespace Root { export type Props = useRender.ComponentProps<'nav'>;}export function Root({ className, render, ...props }: Root.Props) { const defaultProps: useRender.ElementProps<'nav'> & { 'data-slot'?: string } = { 'data-slot': 'breadcrumb', 'aria-label': 'breadcrumb', className: cn(className), }; return useRender({ defaultTagName: 'nav', render, props: mergePropsN<'nav'>([defaultProps, props]), });}/** * An ordered list that contains the breadcrumb items. * Renders an `<ol>` element. * * Documentation: [Caprice UI Breadcrumb](https://caprice-ui.com/docs/components/breadcrumb) */export namespace List { export type Props = useRender.ComponentProps<'ol'>;}export function List({ className, render, ...props }: List.Props) { const defaultProps: useRender.ElementProps<'ol'> & { 'data-slot'?: string } = { 'data-slot': 'breadcrumb-list', className: cn( 'wrap-break-word flex flex-wrap items-center gap-1.5 text-muted-foreground text-sm sm:gap-2.5', className ), }; return useRender({ defaultTagName: 'ol', render, props: mergePropsN<'ol'>([defaultProps, props]), });}/** * A list item that contains a link or page indicator. * Renders an `<li>` element. * * Documentation: [Caprice UI Breadcrumb](https://caprice-ui.com/docs/components/breadcrumb) */export namespace Item { export type Props = useRender.ComponentProps<'li'>;}export function Item({ className, render, ...props }: Item.Props) { const defaultProps: useRender.ElementProps<'li'> & { 'data-slot'?: string } = { 'data-slot': 'breadcrumb-item', className: cn('inline-flex items-center gap-1.5', className), }; return useRender({ defaultTagName: 'li', render, props: mergePropsN<'li'>([defaultProps, props]), });}/** * A navigational link within the breadcrumb trail. * Renders an `<a>` element. * * Documentation: [Caprice UI Breadcrumb](https://caprice-ui.com/docs/components/breadcrumb) */export namespace Link { export type Props = useRender.ComponentProps<'a'>;}export function Link({ className, render, ...props }: Link.Props) { const defaultProps: useRender.ElementProps<'a'> & { 'data-slot'?: string } = { 'data-slot': 'breadcrumb-link', className: cn('transition-colors hover:text-foreground', className), }; return useRender({ defaultTagName: 'a', render, props: mergePropsN<'a'>([defaultProps, props]), });}/** * Indicates the current page in the breadcrumb trail. * Renders a `<span>` element. * * Documentation: [Caprice UI Breadcrumb](https://caprice-ui.com/docs/components/breadcrumb) */export namespace Page { export type Props = useRender.ComponentProps<'span'>;}export function Page({ className, render, ...props }: Page.Props) { const defaultProps: useRender.ElementProps<'span'> & { 'data-slot'?: string } = { 'data-slot': 'breadcrumb-page', role: 'link', 'aria-current': 'page', 'aria-disabled': true, className: cn('font-normal text-foreground', className), }; return useRender({ defaultTagName: 'span', render, props: mergePropsN<'span'>([defaultProps, props]), });}/** * A visual separator between breadcrumb items. * Renders an `<li>` element. * * Documentation: [Caprice UI Breadcrumb](https://caprice-ui.com/docs/components/breadcrumb) */export namespace Separator { export type Props = useRender.ComponentProps<'li'>;}export function Separator({ children = <ChevronRight />, className, render, ...props}: Separator.Props) { const defaultProps: useRender.ElementProps<'li'> & { 'data-slot'?: string } = { 'data-slot': 'breadcrumb-separator', role: 'presentation', 'aria-hidden': true, className: cn('[&>svg]:size-3.5', className), }; return useRender({ defaultTagName: 'li', render, props: mergePropsN<'li'>([defaultProps, props]), });}/** * An indicator for collapsed breadcrumb items when the trail is too long. * Renders a `<span>` element. * * Documentation: [Caprice UI Breadcrumb](https://caprice-ui.com/docs/components/breadcrumb) */export namespace Ellipsis { export type Props = useRender.ComponentProps<'span'>;}export function Ellipsis({ className, render, ...props }: Ellipsis.Props) { const defaultProps: useRender.ElementProps<'span'> & { 'data-slot'?: string } = { 'data-slot': 'breadcrumb-ellipsis', role: 'presentation', 'aria-hidden': true, children: ( <> <MoreHorizontal className="size-4" /> <span className="sr-only">More</span> </> ), className: cn('flex size-9 items-center justify-center', className), }; return useRender({ defaultTagName: 'span', render, props: mergePropsN<'span'>([defaultProps, props]), });}Update the import paths to match your project setup.
Usage
import * as Breadcrumb from "@/components/caprice-ui/breadcrumb"import * as Breadcrumb from "@caprice-ui/react/breadcrumb"Examples
Differences with shadcn/ui
If you're familiar with shadcn/ui, most patterns will carry over. This guide points out the differences so you can start using Caprice UI without surprises.
Key changes
| Feature | shadcn/ui | Caprice UI |
|---|---|---|
| Component API | Flat exports (BreadcrumbLink) | Namespace exports (Breadcrumb.Link) |
| Composition | asChild prop (Link only) | render prop (all components) |
| Primitive | Native HTML + Radix Slot | Base UI useRender |
| Props type | React.ComponentProps<'element'> | useRender.ComponentProps<'element'> |
Comparison Example
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="/">Home</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Current</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>import * as Breadcrumb from '@/components/caprice-ui/breadcrumb'
<Breadcrumb.Root>
<Breadcrumb.List>
<Breadcrumb.Item>
<Breadcrumb.Link render={<Link href="/" />}>Home</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Page>Current</Breadcrumb.Page>
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb.Root>Accessibility
This component follows the WAI-ARIA Breadcrumb Pattern:
- The breadcrumb trail is contained within a navigation landmark region (
<nav>). - The landmark region is labelled via
aria-label="breadcrumb". - The current page is marked with
aria-current="page"to indicate it's not a navigable link. - Separators use
role="presentation"andaria-hidden="true"to hide them from assistive technologies. - The ellipsis includes a visually hidden "More" label for screen readers.
Badge
Display bite-sized snippets of info, like notifications or labels, that you want to stand out from regular text. They're perfect for showing things like unread message counts, status updates or categories without taking up much space.
Button Group
A container that groups a set of buttons sticked together.