v1.0.0 — zero config needed

Breadcrumbs that
write themselves

Define your routes once. Get auto-generated breadcrumbs everywhere — with async labels, SEO JSON-LD injection, and adapters for every major React router.

Get started → View on GitHub
myapp.com/products/123/reviews
Auto-generated breadcrumb — click a path below
npm install breadcrumb-core
The problem
Stop writing breadcrumbs
on every page

Route changes silently break them. Dynamic labels get duplicated. Nobody wins.

products/[id]/reviews.tsx Before
// Written by hand on every page 😩
<Breadcrumb>
  <Item>Home</Item>
  <Item>Products</Item>
  <Item>
    {'{ /* fetch name yourself */}'}
    {product.name}
  </Item>
  <Item>Reviews</Item>
</Breadcrumb>

// Repeat on 40 other pages...
// Route changes = silent breakage 💀
routes.ts + any page After
// Define once ✅
export const routes = [
  { path: "/", label: "Home" },
  { path: "/products", label: "Products" },
  {
    path: "/products/:id",
    label: async ({ params }) =>
      getProductName(params.id)
  },
  { path: "/products/:id/reviews",
    label: "Reviews" },
]

// Any page — zero code needed
<AutoBreadcrumb />
// → Home / Products / iPhone 15 / Reviews
How it works
4 steps. Zero config.

The library reads your route definitions once and handles everything automatically.

1

Parse URL

/products/123/reviews becomes four typed ancestor segments

2

Match routes

Each segment matched against your config with named param extraction

3

Resolve labels

Strings used directly. Async functions awaited and cached for instant back-nav

4

Render

Your <AutoBreadcrumb> renders. Skeleton shown while async resolves

Features
Everything you needed
but couldn't find

The combination no existing solution provides.

⚡

Async labels with cache

Labels can be async functions. Results are cached by path + params so back-navigation is instant. Pass renderSkeleton for a loading state.

🔍

Schema.org JSON-LD

One prop enables automatic BreadcrumbList structured data injection for Google rich results. No extra libraries.

🙈

Hidden segments

Mark layout-only routes with hidden: true and they're skipped in the breadcrumb without affecting your routing at all.

📄

Document title sync

Set syncDocumentTitle and the browser tab updates to iPhone 15 — Products — MyApp automatically on every navigation.

🎨

Headless hook

Use useBreadcrumb() to get raw items and build fully custom renders with your own design system. Zero opinions on markup.

🗜️

Smart collapsing

Set maxItems={4} and deep paths collapse in the middle with … automatically. No extra logic needed.

Adapters
Works with your router

Each adapter reads pathname automatically. Same API, every framework.

react-router v6+
import { AutoBreadcrumb }
from 'breadcrumb-core/react-router'
next.js app router
import { AutoBreadcrumb }
from 'breadcrumb-core/next'
tanstack router v1
import { AutoBreadcrumb }
from 'breadcrumb-core/tanstack-router'
headless any
import { useBreadcrumb }
from 'breadcrumb-core/headless'
Comparison
Why existing tools fall short

2M+ combined weekly npm installs — none covering all the cases.

Tool Async labels SEO JSON-LD Multi-router Headless hook Cache
breadcrumb-core ✦ ✓ ✓ ✓ ✓ ✓
use-react-router-breadcrumbs ✗ ✗ ✗ ✓ ✗
antd Breadcrumb ✗ ✗ ✗ ✗ ✗
Manual per-page ✗ ✗ ✓ ✗ ✗
API reference
Simple. Composable. Typed.

Full TypeScript support. Every prop documented.

<AutoBreadcrumb />

PropDefaultDescription
separator"/"Between items
maxItems—Collapse middle with …
showHometrueInclude root item
injectJsonLdfalseSchema.org JSON-LD
syncDocumentTitlefalseAuto document.title
appName—Appended to synced title
renderItem—Custom item renderer fn
renderSkeleton—Loading placeholder

RouteConfig interface

interface RouteConfig {
  path:   string
  label:
    | string
    | (({ params }) =>
        string | Promise<string>)
  icon?:   ReactNode
  hidden?: boolean
}

// useBreadcrumb() returns:
interface BreadcrumbItem {
  path:     string
  label:    string
  params:   RouteParams
  isLast:   boolean
  icon?:    ReactNode
}

Ship better breadcrumbs
in 5 minutes

One install. One provider. Zero breadcrumb code per page. Ever.

Read the docs → View on GitHub