breadcrumbs-kit
v1.0.0
Published
Headless, modern breadcrumbs management for Next.js, React, and TanStack Router with dynamic crumb portals, RSC support, responsive overflow collapsing, and Schema.org JSON-LD SEO.
Maintainers
Readme
breadcrumbs-kit
Headless, modern breadcrumb engine and UI primitives for React, Next.js (App Router / RSC), and TanStack Router with dynamic crumb portals, Schema.org JSON-LD SEO, and responsive overflow collapsing.
✨ Features
- ⚡️ Next.js App Router & Server Components (RSC): Native support for Server Components (
getServerBreadcrumbs), stripping route groups like(dashboard)or(auth)automatically. - 🎯 Declarative Crumb Teleportation (
<Crumb />): Deep child components can register or override crumb labels/icons without prop-drilling into top-level layouts. - 🔍 First-Class SEO (Schema.org JSON-LD): Auto-generates valid Google-compliant
BreadcrumbListstructured data. - 🪓 Responsive Overflow & Collapsing: Headless hook (
useBreadcrumbOverflow) to auto-collapse long trails into clean ellipsis popovers (...). - 🔄 Async Route Resolvers: Resolve database IDs (
/projects/:id) to human-readable names with built-in loading states and SWR/React Query caching compatibility. - 🎨 100% Headless: Works seamlessly with Tailwind CSS, shadcn/ui, Radix, MUI, Chakra, or custom CSS.
- 📦 Zero-Config & Type-Safe: Pure TypeScript with full ESM and CJS bundles.
📦 Installation
npm install breadcrumbs-kit
# or
pnpm add breadcrumbs-kit
# or
yarn add breadcrumbs-kit🚀 Quick Start
1. Wrap your app with BreadcrumbsProvider
// app/layout.tsx or src/App.tsx
import { BreadcrumbsProvider } from 'breadcrumbs-kit/react';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<BreadcrumbsProvider>
<MyBreadcrumbNav />
{children}
</BreadcrumbsProvider>
</body>
</html>
);
}2. Build your Breadcrumb UI component
'use client';
import { useNextBreadcrumbs } from 'breadcrumbs-kit/next';
import { useBreadcrumbOverflow, BreadcrumbJsonLd } from 'breadcrumbs-kit/react';
import Link from 'next/link';
export function MyBreadcrumbNav() {
const { items, isLoading } = useNextBreadcrumbs({
resolvers: {
'/projects/:id': async ({ id }) => {
const res = await fetch(`/api/projects/${id}`);
const data = await res.json();
return data.name;
},
},
});
const { items: visibleItems, isCollapsed, collapsedItems } = useBreadcrumbOverflow({
items,
maxItems: 4,
});
return (
<>
{/* Schema.org SEO Structured Data */}
<BreadcrumbJsonLd items={items} baseUrl="https://yourdomain.com" />
<nav aria-label="Breadcrumb" className="flex items-center space-x-2 text-sm text-gray-600">
{visibleItems.map((item, index) => (
<span key={item.key} className="inline-flex items-center">
{index > 0 && <span className="mx-2 text-gray-400">/</span>}
{item.disabled ? (
<span className="text-gray-400 font-medium">{item.label}</span>
) : item.isCurrent ? (
<span className="text-gray-900 font-semibold">{item.label}</span>
) : (
<Link href={item.href} className="hover:text-blue-600">
{item.label}
</Link>
)}
</span>
))}
</nav>
</>
);
}3. Declarative Crumb Portals (<Crumb />)
Need a nested page or modal to change the breadcrumb label dynamically? Just drop <Crumb /> in your page:
// app/projects/[id]/page.tsx
import { Crumb } from 'breadcrumbs-kit/react';
export default async function ProjectPage({ params }: { params: { id: string } }) {
const project = await getProject(params.id);
return (
<div>
<Crumb
label={project.name}
href={`/projects/${project.id}`}
icon={<FolderIcon className="w-4 h-4 mr-1" />}
/>
<h1 className="text-2xl font-bold">{project.name}</h1>
</div>
);
}⚡️ Next.js Server Components (RSC) & SEO
For purely static pages or generating SEO metadata directly on the server without any client hydration:
import { getServerBreadcrumbs, generateServerBreadcrumbsJsonLd } from 'breadcrumbs-kit/next';
export async function generateMetadata({ params }) {
const jsonLd = await generateServerBreadcrumbsJsonLd(`/projects/${params.id}`, {
baseUrl: 'https://example.com',
resolvers: {
'/projects/:id': async () => 'Custom Project Name',
},
});
return {
other: {
'script:ld+json': JSON.stringify(jsonLd),
},
};
}🛠 API Reference
Core & React Exports
useBreadcrumbs(options)useNextBreadcrumbs(options)useBreadcrumbOverflow(options)<BreadcrumbsProvider><Crumb label="..." href="..." icon="..." /><BreadcrumbJsonLd items={...} baseUrl="..." />getServerBreadcrumbs(pathname, options)formatSlugToTitle(segment)generateBreadcrumbJsonLd(items, options)
📄 License
MIT © Antigravity Open Source
