Breadcrumb

Shows where the page sits in the product and gives a link to each level above it.

Examples

A run four levels deep

Giving ground as the box narrows

560px
320px
200px

Parts, for a fixed trail

An ID as the current page

Fit

States

Usage

When to use it
Use
The page is three or more levels deep: workspace, agent, run.
Use
A detail page needs a way back to its list and to the levels above.
Not for
The page is a peer of its neighbours, like Runs next to Keys. Use Tabs.
Not for
The person pages through results. Use Pagination.
Not for
The page is one level below home. The page header title is enough.

Rules

7 rules
Should
Use BreadcrumbTrail with items; compose the parts by hand only for a fixed trail of three or fewer. Because the trail measures its container and folds crumbs into a menu in a fixed order, which hand-built parts do not.
Must
Make the last item the current page, with no href. Because the current page is ink and not a link, and aria-current="page" tells a screen reader where it is.
Must
Order items from the root to the current page. Because the trail folds from the left and keeps the current page last, so a reversed list folds the wrong crumbs.
Must
Set an ID crumb with id: true or BreadcrumbId. Because it sets the ID in mono and cuts the middle while keeping the type prefix, so run_8f2a…e5b6a7 stays readable.
Must
Pass renderLink with your router link so a press does not reload the page. Because without it every crumb is a plain anchor and each press is a full page load.
Should
Use the page title as the crumb label, and a short noun for a list level. Because a crumb that names a page differently from its heading sends the person to a place they do not recognise.
Never
Render two breadcrumbs on one page. Because each is a nav landmark with the same name, so a screen reader cannot tell them apart.

Accessibility

5 checks
The root is a nav named "Breadcrumb" holding an ordered list; the separators are aria-hidden.
The current page has aria-current="page" and is not a link.
The fold button names its count ("2 more levels") and opens a menu of links with arrow keys and Escape.
A cut current page carries its full text as a title, and an ID crumb keeps the whole ID for screen readers.
Links show a 2px ink outline on focus and underline on hover; touch targets are at least 24px tall.

Edge cases

8 edge cases
Trail too wide
Middle crumbs fold into a "…" menu from the left, then the current page truncates, then the root joins the menu.
Current page
Never shrinks below 8ch and the trail never ends in a slash.
One item
Renders the current page alone; it truncates if it does not fit.
Long ID
Past 18 characters it shows the type prefix and 4 characters, an ellipsis and the last 6.
First paint
It measures a hidden copy before it decides, so nothing jumps while it folds.
Container resizes
It measures again and unfolds as room returns.
Right to left
The trail mirrors; labels use dir="auto".
Zoom 200%
More crumbs fold sooner, and every folded one stays one menu press away.

API

5 props
items
Crumb[] default required
renderLink
(href: string) => ReactElement
Crumb id
boolean default false
Breadcrumb parts
BreadcrumbList, Item, Link, Page, Separator, Ellipsis
className
string

Tokens

11 tokens
--crumb-floor
8ch
--radius-inner
4px
--radius-soft
6px
--text-1
var(--ink)
--text-2
oklch(var(--ink-c) / 0.80)
--text-3
oklch(var(--ink-c) / 0.66)
--surface-hover
oklch(var(--ink-c) / 0.05)
--surface-pressed
oklch(var(--ink-c) / 0.08)
--popover
288px
--type-label
400 14px/16px var(--font-sans)
--type-tag
var(--type-code-sm)

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.