Breadcrumb Block
Breadcrumbs is a navigation trail built on MUI Breadcrumbs, with a primary bar style and chevron separators.
Installation
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-breadcrumb-block
yarn add @nodeblocks/frontend-breadcrumb-block
pnpm add @nodeblocks/frontend-breadcrumb-block
bun add @nodeblocks/frontend-breadcrumb-block
What You Need
| Item | Why it matters |
|---|---|
items (optional) | Renders the trail from { label, url? } segments (default pattern) |
Breadcrumbs.Item (optional) | Build the trail with compound children instead of items |
onNavigate (optional) | Called with the clicked segment href for client-side routing |
children (function, optional) | Override defaultBlocks and blockOrder |
Use the items prop for the simplest trail (see Quick Start). Use Breadcrumbs.Item compound children when you want full control per segment—the items prop is ignored when children are JSX elements (not a function). Use a function child with defaultBlocks and blockOrder for custom keys, order, or non-link nodes; omit items unless you want those segments rendered before your blockOrder blocks. MUI inserts separators between children—do not add manual chevron elements.
Code Examples
- Quick Start
- Items and navigation
- Compound Components
- Block Override
function Example() { const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs items={[ { label: 'Home', url: '#home' }, { label: 'Products', url: '#products' }, { label: 'Shoes' }, ]} onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} /> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
Control collapse behavior and handle navigation from segment clicks.
function Example() { const items = [ { label: 'Home', url: '#home' }, { label: 'Products', url: '#products' }, { label: 'Electronics', url: '#electronics' }, { label: 'Computers', url: '#computers' }, { label: 'Laptops', url: '#laptops' }, { label: 'MacBook Pro' }, ]; const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs items={items} maxItems={4} itemsBeforeCollapse={1} itemsAfterCollapse={2} onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} /> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
Omit url on the last items entry (or omit href on the last Breadcrumbs.Item) to show the current page without a link.
Use Breadcrumbs.Item for each segment. MUI renders chevrons via the root separator (default ChevronRight icon).
function Example() { const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs items={undefined} onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} > <Breadcrumbs.Item href="#home">Home</Breadcrumbs.Item> <Breadcrumbs.Item href="#products">Products</Breadcrumbs.Item> <Breadcrumbs.Item>Shoes</Breadcrumbs.Item> </Breadcrumbs> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
If your demo keeps an items arg around, clear it when switching to compound children so the props panel reflects the JSX-children pattern. The component itself ignores items whenever children is JSX rather than a function.
Use function children to set custom blocks and order. Omit items unless you want the items trail rendered before your blockOrder blocks.
function Example() { const [lastEvent, setLastEvent] = React.useState('Ready'); return ( <> <Breadcrumbs onNavigate={(url) => { setLastEvent(`Navigate: ${url}`); }} > {({ defaultBlocks, defaultBlockOrder }) => ({ blocks: { ...defaultBlocks, home: <Breadcrumbs.Item href="#home">Home</Breadcrumbs.Item>, products: <Breadcrumbs.Item href="#products">Products</Breadcrumbs.Item>, current: ( <span style={{ fontSize: 12, color: 'inherit', opacity: 0.9 }}>Shoes</span> ), }, blockOrder: ['home', 'products', 'current'], })} </Breadcrumbs> <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>{lastEvent}</div> </> ); }
When to use block overrides
Use overrides when you need a fixed block order, a non-link current page, or custom nodes in the trail while keeping the default bar styling and MUI separator behavior. Default blockOrder is ['item'] (defaultBlockOrder); the default item block is only rendered when that key is listed in blockOrder and present in blocks.
To append segments (Storybook pattern):
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
suffix: <Breadcrumbs.Item href="#more">More</Breadcrumbs.Item>,
},
blockOrder: [...defaultBlockOrder, 'suffix'],
})}
Omit 'item' from blockOrder if you spread defaultBlocks but do not want the placeholder item block.
Important Props
Core Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
items | readonly { label: ReactNode; url?: string; onClick?: React.MouseEventHandler<HTMLAnchorElement> }[] | No | undefined | Trail segments; omit url on the current page; optional per-item onClick |
onNavigate | (url: string) => void | No | undefined | Called when a segment with href / url is clicked (runs after the segment’s onClick, if any) |
maxItems | number | No | 8 | Maximum visible items before MUI collapses the trail |
itemsBeforeCollapse | number | No | 1 | Items shown before the collapse ellipsis |
itemsAfterCollapse | number | No | 1 | Items shown after the collapse ellipsis |
Content Props
| Component | Prop | Type | Required | Default | Description |
|---|---|---|---|---|---|
Item | href | string | No | undefined | Link target; omit for the current (non-link) segment |
Item | children | ReactNode | Yes | - | Label for the segment |
Item | component | React.ElementType | No | 'a' | Root element for the link |
Item | onClick | React.MouseEventHandler<HTMLAnchorElement> | No | undefined | Click handler; onNavigate still runs when href is a string |
Breadcrumbs (root) | separator | ReactNode | No | MUI ChevronRight icon | Separator between segments |
Layout and Composition Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | BlocksOverride | ReactNode | No | undefined | Breadcrumbs.Item elements or function override returning blocks and blockOrder |
className | string | No | undefined | Class name for the root container (nbb-breadcrumb is applied by default) |
sx | SxProps | No | undefined | MUI system styles for the root container |
Breadcrumbs inherits BreadcrumbsProps from MUI (except children), including expandText and slotProps. Default blockOrder without overrides is ['item'] (defaultBlockOrder).
Default UI Blocks
| Block | Built on | Notes |
|---|---|---|
Breadcrumbs (root) | Breadcrumbs | Primary bar (bgcolor: primary.main); separator default ChevronRight |
Breadcrumbs.Item | Link | Segment link (nbb-breadcrumb-item); uses href, calls onNavigate when set |
TypeScript
import { Breadcrumbs } from '@nodeblocks/frontend-breadcrumb-block';
import type { MouseEventHandler, ReactNode } from 'react';
// Same shape as the package's BreadcrumbNavItem (not re-exported from the entry point).
type TrailItem = {
label: ReactNode;
url?: string;
onClick?: MouseEventHandler<HTMLAnchorElement>;
};
const trail: TrailItem[] = [
{ label: 'Home', url: '/home' },
{ label: 'Products', url: '/products' },
{ label: 'Shoes' },
];
<Breadcrumbs items={trail} onNavigate={(url) => router.push(url)} />;