Breadcrumbs

One click back up the hierarchy. A compound Breadcrumbs with type, divider, and maxVisibleItems, ellipsis folding, and an AccountItem workspace switcher.

Demo

Change the props and copy the result. Type, divider, and maxVisibleItems are real props; the snippet emits the crumbs.

type
divider
Trail length
maxVisibleItems
import { Home01 } from "@untitledui/icons"; import { Breadcrumbs } from "@/components/application/breadcrumbs/breadcrumbs"; <Breadcrumbs> <Breadcrumbs.Item href="#" icon={Home01} /> <Breadcrumbs.Item href="#">Projects</Breadcrumbs.Item> <Breadcrumbs.Item href="#">Marketing site redesign</Breadcrumbs.Item> <Breadcrumbs.Item href="#">Assets</Breadcrumbs.Item> <Breadcrumbs.Item href="#">Brand</Breadcrumbs.Item> <Breadcrumbs.Item>Logos</Breadcrumbs.Item> </Breadcrumbs>

Two props, set once, delivered by context

type and divider live on the container and reach every crumb through React context. Breadcrumbs.Item accepts both and then overwrites them from that context, so setting them per crumb type-checks and does nothing.

Contextual demo

A trail is chrome. It only reads correctly with a page underneath and an app frame around it, so it gets a whole screen.

The family

Three exports: the container, the crumb, and the account crumb.

The components in this family, with their descriptions and import paths
ComponentDescriptionImport from
BreadcrumbsThe nav landmark and the list: owns type, divider, and maxVisibleItems, and hands the first two to its items through context.@/​components/​application/​breadcrumbs/​breadcrumbs
Breadcrumbs.ItemOne crumb: a link with an optional leading icon, or an avatar in a ring when avatarSrc is set. The last one is styled as the current page.@/​components/​application/​breadcrumbs/​breadcrumb-item
Breadcrumbs.AccountItemA workspace or account crumb: an avatar, a name, and a chevron opening a single-select dropdown of accounts; below md, the ringed avatar alone.@/​components/​application/​breadcrumbs/​breadcrumb-account-item

Built from

Nine pieces make up the trail and its account switcher; four have their own docs page.

Component
Where it’s used here
AvatarThe portrait in an avatarSrc crumb and in the account crumb, at size xs.
DropdownThe account switcher menu and its popover.
RadioButtonBaseThe selected marker on each row of that menu.
@untitledui/iconsChevronRight, SlashDivider, and ChevronSelectorVertical.

Types

Three type values, each with both dividers: six live rows. The sheet’s twelve symbols repeat these at two breakpoints.

type text
divider chevron
divider slash
type text-line
divider chevron
divider slash
type button
divider chevron
divider slash

text-line stretches; the other two do not

The rules on text-line are drawn by an absolutely positioned after pseudo-element on the list, so they run the width of the list rather than the width of the container. In a page they usually want a wrapper that fills the column.

Dividers

Both glyphs, side by side at the same type, since the difference is easy to describe and hard to picture.

divider chevron
divider slash

Collapsing a deep trail

maxVisibleItems folds a long trail’s middle behind an ellipsis — a real control: select it and the trail expands.

Six levels, maxVisibleItems 4 (the default): 4 crumbs
Six levels, maxVisibleItems 3: exactly 3 crumbs
Six levels, maxVisibleItems 0: collapsing off, and the row runs 522px wide from 768px up, 502px below it

Expanding resets when the crumbs change

The ellipsis sets an internal flag to expanded, and it resets on its own the next time the trail’s own crumbs change — a route change swapping in a different set, for instance. The rows above pass the same fixed crumb array on every render, so nothing here ever triggers that reset; reload the page if you want to collapse them again.

The account crumb

A workspace crumb in both shapes: a plain avatar crumb that navigates, and the dropdown that switches.

AccountItem with a chevron divider: select the name to switch, or the avatar alone below 768px
The same row with a slash divider

Two shapes, one look from 768px up

The first crumb in each row is a plain Breadcrumbs.Item avatarSrc: the same avatar in the same ring, as a link with no menu. The second is Breadcrumbs.AccountItem, which adds the switcher chevron and the dropdown. Below 768px, since the 2026-08-22 edit, the second drops its visible label and the chevron and is the ringed avatar alone, while the first keeps its label at every width: measured at 390×844, the trigger is 28px wide rather than 108.7px. Use the first when there is nothing to switch to.

States

The crumb has three: default, hover, and focus. Current is not set — it is what the last crumb in the list gets.

Hover and focus a crumb: text goes one step darker, and the focus ring sits 2px outside it, on a 4px corner
Type button: hover and current both fill the pill, on a 6px corner
Current: the last crumb, painted brand, with no divider after it
A long current label in a 220px column: the current crumb truncates, and only the current one

Truncation is the current crumb’s, and the account crumb’s

Measured in the cell above, at a 1440px window: the label wants 268px, gets 81px, and ends in an ellipsis. Below 768px it gets 89px in the same 220px column, because the tighter gaps leave it more room. Every other crumb is whitespace-nowrap with nothing clipping it, so a long ancestor label pushes the row wider instead. Since 2026-08-22 the account crumb’s name truncates as well, on the trigger and on each menu row, as the sheet ellipsizes a long workspace name.

There is no disabled crumb

Neither the sheet nor the kit draws one, and leaving the href off does not make one: only the current crumb is disabled, by React Aria, and a non-final crumb with no href stays focusable and is still announced as a link, going nowhere. A crumb you do not want followed is a crumb you leave out.