Breadcrumb
SM, under 950B gzippedA landmark trail with the current page marked aria-current.
- Category
- Navigation
- Budget
- sm, single-purpose control
- Runtime deps
- None
Preview
This is the exact fixture the conformance suite renders in CI. Switch the language to see the component mirror and reformat.
Install
npx shadcn@latest add https://kata-ui-rho.vercel.app/r/breadcrumb.jsonCopies the source into your project. Pulls in 2 primitives: sanitize, cn.
Source
import { sanitizeHref } from "../lib/sanitize";
import { cn } from "../lib/cn";
export interface BreadcrumbItem {
label: string;
href?: string;
}
export interface BreadcrumbProps {
items: BreadcrumbItem[];
/** Auto-mirrors under RTL: rendered via `rtl:` variants, not hardcoded. */
separator?: string;
className?: string;
}
/**
* `<nav aria-label="Breadcrumb">` around an ordered list, with the current
* page marked `aria-current="page"` — the separator is decorative and
* `aria-hidden`, so a screen reader hears "Home, Products, current page:
* Shoes" instead of a stream of ">" characters.
*/
export function Breadcrumb({ items, separator = "/", className }: BreadcrumbProps) {
return (
<nav aria-label="Breadcrumb" className={className}>
<ol className="flex flex-wrap items-center gap-1.5 text-sm text-neutral-600 dark:text-neutral-400">
{items.map((item, index) => {
const isLast = index === items.length - 1;
return (
<li key={`${item.label}-${index}`} className="flex items-center gap-1.5">
{item.href && !isLast ? (
<a href={sanitizeHref(item.href)} className="hover:text-neutral-900 hover:underline dark:hover:text-neutral-100">
{item.label}
</a>
) : (
<span aria-current={isLast ? "page" : undefined} className={cn(isLast && "font-medium text-neutral-900 dark:text-neutral-100")}>
{item.label}
</span>
)}
{!isLast && (
<span aria-hidden="true" className="text-neutral-400">
{separator}
</span>
)}
</li>
);
})}
</ol>
</nav>
);
}
What CI checks
- Bundled, minified and gzipped against its tier budget
- Audited by axe in the state previewed above
- Rendered through react-dom/server with no browser globals
- Scanned for network calls, dangerous sinks, and unguarded animation