UI/UI
Breadcrumb
A navigation aid that shows users their current location within a website or application hierarchy.
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/docs">Documentation</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
Installation
Install following dependencies:
npm install @radix-ui/react-slot class-variance-authority lucide-react
pnpm add @radix-ui/react-slot class-variance-authority lucide-react
yarn add @radix-ui/react-slot class-variance-authority lucide-react
bun add @radix-ui/react-slot class-variance-authority lucide-react
Copy and paste the following code into your project.
"use client";
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { ChevronRight, MoreHorizontal } from "lucide-react";
import { cn } from "@/lib/utils";
const breadcrumbVariants = cva("", {
variants: {},
defaultVariants: {},
});
const breadcrumbListVariants = cva(
"flex flex-wrap items-center gap-1.5 break-words text-sm text-[hsl(var(--hu-muted-foreground))]",
{
variants: {
size: {
sm: "text-xs gap-1",
default: "text-sm gap-1.5",
lg: "text-base gap-2",
},
},
defaultVariants: {
size: "default",
},
},
);
const breadcrumbItemVariants = cva("inline-flex items-center gap-1.5", {
variants: {},
defaultVariants: {},
});
const breadcrumbLinkVariants = cva(
"transition-colors hover:text-[hsl(var(--hu-foreground))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--hu-ring))] focus-visible:ring-offset-2 rounded-sm flex items-center gap-1",
{
variants: {},
defaultVariants: {},
},
);
const breadcrumbPageVariants = cva(
"font-normal text-[hsl(var(--hu-foreground))]",
{
variants: {
variant: {
default: "",
highlighted: "font-medium",
muted: "text-[hsl(var(--hu-muted-foreground))]",
},
},
defaultVariants: {
variant: "default",
},
},
);
export interface BreadcrumbProps extends React.ComponentPropsWithoutRef<"nav"> {
separator?: React.ReactNode;
}
export interface BreadcrumbListProps
extends React.ComponentPropsWithoutRef<"ol">,
VariantProps<typeof breadcrumbListVariants> {}
export interface BreadcrumbItemProps
extends React.ComponentPropsWithoutRef<"li"> {}
export interface BreadcrumbLinkProps
extends React.ComponentPropsWithoutRef<"a"> {
asChild?: boolean;
}
export interface BreadcrumbPageProps
extends React.ComponentPropsWithoutRef<"span">,
VariantProps<typeof breadcrumbPageVariants> {}
export interface BreadcrumbSeparatorProps extends React.ComponentProps<"li"> {
children?: React.ReactNode;
}
export interface BreadcrumbEllipsisProps extends React.ComponentProps<"span"> {}
const Breadcrumb = React.forwardRef<HTMLElement, BreadcrumbProps>(
({ className, ...props }, ref) => (
<nav
ref={ref}
aria-label="breadcrumb"
className={cn(breadcrumbVariants({}), className)}
{...props}
/>
),
);
Breadcrumb.displayName = "Breadcrumb";
const BreadcrumbList = React.forwardRef<HTMLOListElement, BreadcrumbListProps>(
({ className, size, ...props }, ref) => (
<ol
ref={ref}
className={cn(breadcrumbListVariants({ size }), className)}
{...props}
/>
),
);
BreadcrumbList.displayName = "BreadcrumbList";
const BreadcrumbItem = React.forwardRef<HTMLLIElement, BreadcrumbItemProps>(
({ className, ...props }, ref) => (
<li
ref={ref}
className={cn(breadcrumbItemVariants({}), className)}
{...props}
/>
),
);
BreadcrumbItem.displayName = "BreadcrumbItem";
const BreadcrumbLink = React.forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(
({ asChild, className, ...props }, ref) => {
const Comp = asChild ? Slot : "a";
return (
<Comp
ref={ref}
className={cn(breadcrumbLinkVariants({}), className)}
{...props}
/>
);
},
);
BreadcrumbLink.displayName = "BreadcrumbLink";
const BreadcrumbPage = React.forwardRef<HTMLSpanElement, BreadcrumbPageProps>(
({ className, variant, ...props }, ref) => (
<span
ref={ref}
role="link"
aria-disabled="true"
aria-current="page"
className={cn(breadcrumbPageVariants({ variant }), className)}
{...props}
/>
),
);
BreadcrumbPage.displayName = "BreadcrumbPage";
const BreadcrumbSeparator: React.FC<BreadcrumbSeparatorProps> = ({
children,
className,
...props
}) => (
<li
role="presentation"
aria-hidden="true"
className={cn(
"flex items-center [&>svg]:size-3.5 [&>svg]:shrink-0",
className,
)}
{...props}
>
{children ?? <ChevronRight />}
</li>
);
BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
const BreadcrumbEllipsis: React.FC<BreadcrumbEllipsisProps> = ({
className,
...props
}) => (
<span
role="presentation"
aria-hidden="true"
className={cn("flex h-9 w-9 items-center justify-center", className)}
{...props}
>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More</span>
</span>
);
BreadcrumbEllipsis.displayName = "BreadcrumbEllipsis";
export {
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
breadcrumbVariants,
breadcrumbListVariants,
breadcrumbItemVariants,
breadcrumbLinkVariants,
breadcrumbPageVariants,
};
npx hextaui@latest add breadcrumb
pnpm dlx hextaui@latest add breadcrumb
yarn dlx hextaui@latest add breadcrumb
bun x hextaui@latest add breadcrumb
Usage
import {
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Current Page</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
Examples
Default
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
With Custom Separator
import { Slash } from "lucide-react";
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbLink href="/products">Products</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbPage>Laptop</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
Sizes
<Breadcrumb>
<BreadcrumbList size="sm">
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Small</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<Breadcrumb>
<BreadcrumbList size="default">
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Default</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<Breadcrumb>
<BreadcrumbList size="lg">
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Large</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
With Icons
import { Home } from "lucide-react";
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">
<Home className="h-4 w-4" />
Home
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/docs">Documentation</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
Collapsed with Ellipsis
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbEllipsis />
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/docs/components">Components</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
With Next.js Link
You can use the asChild
prop to make the breadcrumb link work with Next.js Link or other routing libraries.
import Link from "next/link";
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="/">Home</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link href="/products">Products</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Laptop</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
Props
Breadcrumb
Prop | Type | Default |
---|---|---|
className? | string | undefined |
separator? | React.ReactNode | undefined |
BreadcrumbList
Prop | Type | Default |
---|---|---|
className? | string | undefined |
size? | "sm" | "default" | "lg" | "default" |
BreadcrumbItem
Prop | Type | Default |
---|---|---|
className? | string | undefined |
BreadcrumbLink
Prop | Type | Default |
---|---|---|
className? | string | undefined |
href? | string | undefined |
asChild? | boolean | false |
BreadcrumbPage
Prop | Type | Default |
---|---|---|
className? | string | undefined |
variant? | "default" | "highlighted" | "muted" | "default" |
BreadcrumbSeparator
Prop | Type | Default |
---|---|---|
className? | string | undefined |
children? | React.ReactNode | <ChevronRight /> |
BreadcrumbEllipsis
Prop | Type | Default |
---|---|---|
className? | string | undefined |
Edit on GitHub
Last updated on