Skip to main content

Breadcrumbs

The Breadcrumbs component provides accessible navigation hierarchy for React applications. It shows the current page location within the application structure with full keyboard navigation support and customizable appearance.

Features

  • Accessible Navigation - Full WCAG 2.1 AA compliance with proper ARIA labels
  • Keyboard Support - Complete keyboard navigation with Tab, Enter, and Space
  • Customizable Appearance - Custom separators, icons, and styling
  • Smart Truncation - Automatic ellipsis for long navigation paths
  • Hook Integration - Built-in state management hook
  • Responsive Design - Adapts to different screen sizes

Basic Usage

import { Breadcrumbs } from '@qwickapps/react-framework';

const breadcrumbItems = [
{ label: 'Home', href: '/' },
{ label: 'Products', href: '/products' },
{ label: 'Electronics', href: '/products/electronics' },
{ label: 'Laptop', href: '/products/electronics/laptop', current: true },
];

function Navigation() {
return <Breadcrumbs items={breadcrumbItems} />;
}

With Icons

import { Breadcrumbs } from '@qwickapps/react-framework';
import { HomeIcon, FolderIcon, FileIcon } from '@icons/react';

const breadcrumbsWithIcons = [
{
label: 'Home',
href: '/',
icon: <HomeIcon />
},
{
label: 'Documents',
href: '/documents',
icon: <FolderIcon />
},
{
label: 'Report.pdf',
href: '/documents/report.pdf',
icon: <FileIcon />,
current: true
},
];

function FileNavigation() {
return (
<Breadcrumbs
items={breadcrumbsWithIcons}
separator=""
/>
);
}

Custom Navigation Handler

import { Breadcrumbs } from '@qwickapps/react-framework';
import { useRouter } from 'next/router';

function AppNavigation() {
const router = useRouter();

const handleNavigate = (item, index) => {
// Custom navigation logic
if (item.href) {
router.push(item.href);
}
};

return (
<Breadcrumbs
items={breadcrumbItems}
onNavigate={handleNavigate}
/>
);
}

Dynamic Breadcrumbs with Hook

import { Breadcrumbs, useBreadcrumbs } from '@qwickapps/react-framework';

function DynamicNavigation() {
const {
breadcrumbs,
addBreadcrumb,
removeBreadcrumb,
setBreadcrumbs,
clearBreadcrumbs
} = useBreadcrumbs();

const navigateToSection = (section) => {
setBreadcrumbs([
{ label: 'Home', href: '/' },
{ label: section.name, href: section.url, current: true }
]);
};

const addSubsection = (subsection) => {
addBreadcrumb({
label: subsection.name,
href: subsection.url,
current: true
});
};

return (
<div>
<Breadcrumbs items={breadcrumbs} />

<div>
<button onClick={() => addSubsection({ name: 'New Section', url: '/new' })}>
Add Level
</button>
<button onClick={() => removeBreadcrumb(breadcrumbs.length - 1)}>
Go Back
</button>
<button onClick={clearBreadcrumbs}>
Reset Navigation
</button>
</div>
</div>
);
}

Truncated Long Paths

// Long navigation paths are automatically truncated
const longPath = [
{ label: 'Home', href: '/' },
{ label: 'Level 1', href: '/level1' },
{ label: 'Level 2', href: '/level1/level2' },
{ label: 'Level 3', href: '/level1/level2/level3' },
{ label: 'Level 4', href: '/level1/level2/level3/level4' },
{ label: 'Current Page', href: '/level1/level2/level3/level4/current', current: true },
];

function TruncatedNavigation() {
return (
<Breadcrumbs
items={longPath}
maxItems={4} // Shows: Home > ... > Level 4 > Current Page
/>
);
}

Props

PropTypeDefaultDescription
itemsBreadcrumbItem[]requiredArray of breadcrumb items
separatorReactNode'/'Custom separator between items
classNamestring''Additional CSS classes
onNavigate(item, index) => void-Navigation handler (overrides href)
maxItemsnumber-Maximum items before truncation
showRootbooleantrueWhether to show the first item
interface BreadcrumbItem {
label: string; // Display text
href?: string; // Link destination
icon?: ReactNode; // Optional icon
current?: boolean; // Mark as current page
}

useBreadcrumbs Hook

Provides state management for dynamic breadcrumb navigation:

const {
breadcrumbs, // Current breadcrumb items
addBreadcrumb, // Add item to end
removeBreadcrumb, // Remove item by index
setBreadcrumbs, // Replace all items
clearBreadcrumbs // Remove all items
} = useBreadcrumbs();

Hook Methods

MethodSignatureDescription
addBreadcrumb(item: BreadcrumbItem) => voidAdd new breadcrumb to the end
removeBreadcrumb(index: number) => voidRemove breadcrumb at index
setBreadcrumbs(items: BreadcrumbItem[]) => voidReplace entire breadcrumb array
clearBreadcrumbs() => voidRemove all breadcrumbs

Accessibility Features

ARIA Support

  • role="navigation" with aria-label="Breadcrumb navigation"
  • aria-current="page" on current page item
  • Proper semantic markup with ordered list

Keyboard Navigation

  • Tab - Navigate between breadcrumb links
  • Enter - Activate breadcrumb link
  • Space - Activate breadcrumb link (alternative)

Screen Reader Support

  • Announces breadcrumb navigation context
  • Identifies current page location
  • Properly labels interactive elements

Styling

Default Styles

Breadcrumbs includes sensible default styles:

.breadcrumbs {
display: flex;
align-items: center;
font-size: 14px;
color: #6b7280;
padding: 8px 0;
}

.breadcrumbs ol {
display: flex;
align-items: center;
list-style: none;
margin: 0;
padding: 0;
gap: 8px;
}

.breadcrumbs a {
transition: color 0.2s ease;
cursor: pointer;
border-radius: 4px;
padding: 4px;
text-decoration: none;
}

Custom Styling

<Breadcrumbs 
items={items}
className="custom-breadcrumbs"
style={{
backgroundColor: '#f5f5f5',
borderRadius: '8px',
padding: '12px 16px'
}}
/>
.custom-breadcrumbs a {
color: #2563eb;
font-weight: 500;
}

.custom-breadcrumbs a:hover {
color: #1d4ed8;
background-color: #dbeafe;
}

.custom-breadcrumbs [aria-current="page"] {
color: #1f2937;
font-weight: 600;
}

Examples

E-commerce Product Navigation

function ProductBreadcrumbs({ category, subcategory, product }) {
const breadcrumbs = [
{ label: 'Home', href: '/', icon: <HomeIcon /> },
{ label: 'Products', href: '/products' },
{ label: category.name, href: `/products/${category.slug}` },
{ label: subcategory.name, href: `/products/${category.slug}/${subcategory.slug}` },
{ label: product.name, href: product.url, current: true },
];

return (
<Breadcrumbs
items={breadcrumbs}
separator=""
onNavigate={(item) => {
// Track breadcrumb navigation
analytics.track('breadcrumb_click', { item: item.label });
}}
/>
);
}

File System Navigation

function FileBrowser({ path }) {
const pathSegments = path.split('/').filter(Boolean);

const breadcrumbs = [
{ label: 'Root', href: '/', icon: <FolderIcon /> },
...pathSegments.map((segment, index) => ({
label: segment,
href: '/' + pathSegments.slice(0, index + 1).join('/'),
icon: index === pathSegments.length - 1 ? <FileIcon /> : <FolderIcon />,
current: index === pathSegments.length - 1
}))
];

return (
<Breadcrumbs
items={breadcrumbs}
maxItems={5}
/>
);
}

Admin Dashboard Navigation

function AdminBreadcrumbs() {
const { breadcrumbs, setBreadcrumbs } = useBreadcrumbs();
const location = useLocation();

useEffect(() => {
// Update breadcrumbs based on current route
const pathSegments = location.pathname.split('/').filter(Boolean);

const newBreadcrumbs = [
{ label: 'Dashboard', href: '/admin', icon: <DashboardIcon /> },
...pathSegments.map((segment, index) => {
const href = '/admin/' + pathSegments.slice(0, index + 1).join('/');
return {
label: formatSegmentName(segment),
href,
current: index === pathSegments.length - 1
};
})
];

setBreadcrumbs(newBreadcrumbs);
}, [location.pathname, setBreadcrumbs]);

return <Breadcrumbs items={breadcrumbs} />;
}

function formatSegmentName(segment) {
return segment.charAt(0).toUpperCase() + segment.slice(1).replace('-', ' ');
}

Multi-step Form Navigation

function FormStepBreadcrumbs({ currentStep, steps }) {
const breadcrumbs = steps.map((step, index) => ({
label: step.title,
href: step.url,
current: index === currentStep,
icon: index < currentStep ? <CheckIcon /> : <StepIcon />
}));

return (
<Breadcrumbs
items={breadcrumbs}
separator=""
onNavigate={(item, index) => {
// Only allow navigation to completed steps
if (index < currentStep) {
navigateToStep(index);
}
}}
/>
);
}

Best Practices

  1. Provide Context - Always include a root/home breadcrumb
  2. Mark Current Page - Use current: true for the active page
  3. Use Semantic Icons - Choose icons that represent the content type
  4. Handle Long Paths - Use maxItems for deep navigation hierarchies
  5. Custom Navigation - Implement onNavigate for SPA routing
  6. Consistent Separators - Use the same separator throughout your app
  7. Keyboard Testing - Ensure all breadcrumbs are keyboard accessible

Integration with Routing Libraries

Next.js

import { useRouter } from 'next/router';

function NextBreadcrumbs({ items }) {
const router = useRouter();

return (
<Breadcrumbs
items={items}
onNavigate={(item) => router.push(item.href)}
/>
);
}

React Router

import { useNavigate } from 'react-router-dom';

function RouterBreadcrumbs({ items }) {
const navigate = useNavigate();

return (
<Breadcrumbs
items={items}
onNavigate={(item) => navigate(item.href)}
/>
);
}