Breadcrumb navigation component following the shadcn/ui Breadcrumb anatomy.
Breadcrumbs communicate the current page's location within the site hierarchy and allow users to navigate upward. This implementation is purely HEEx with no JavaScript required. Full WAI-ARIA support is included out of the box.
Sub-components
| Component | Element | Purpose |
|---|---|---|
breadcrumb/1 | <nav> | Landmark wrapper with aria-label="breadcrumb" |
breadcrumb_list/1 | <ol> | Ordered flex container for items |
breadcrumb_item/1 | <li> | Individual item wrapper |
breadcrumb_link/1 | <a> | Navigable ancestor link |
breadcrumb_page/1 | <span> | Current page label (aria-current="page") |
breadcrumb_separator/1 | <li> | Visual separator (default: /) |
breadcrumb_ellipsis/1 | <span> | Collapsed path indicator (…) |
Basic usage
<.breadcrumb>
<.breadcrumb_list>
<.breadcrumb_item>
<.breadcrumb_link href="/">Home</.breadcrumb_link>
</.breadcrumb_item>
<.breadcrumb_separator />
<.breadcrumb_item>
<.breadcrumb_link href="/settings">Settings</.breadcrumb_link>
</.breadcrumb_item>
<.breadcrumb_separator />
<.breadcrumb_item>
<.breadcrumb_page>Profile</.breadcrumb_page>
</.breadcrumb_item>
</.breadcrumb_list>
</.breadcrumb>Nested resource navigation
Useful when displaying a deeply-nested record in an admin panel, e.g.
Organizations > Acme Corp > Teams > Engineering > Members > Jane:
<.breadcrumb>
<.breadcrumb_list>
<.breadcrumb_item>
<.breadcrumb_link navigate={~p"/organizations"}>Organizations</.breadcrumb_link>
</.breadcrumb_item>
<.breadcrumb_separator />
<.breadcrumb_item>
<.breadcrumb_link navigate="/organizations/acme">
Acme Corp
</.breadcrumb_link>
</.breadcrumb_item>
<.breadcrumb_separator />
<%!-- Collapse intermediate levels on small viewports --%>
<.breadcrumb_item>
<.breadcrumb_ellipsis />
</.breadcrumb_item>
<.breadcrumb_separator />
<.breadcrumb_item>
<.breadcrumb_page>{@member.name}</.breadcrumb_page>
</.breadcrumb_item>
</.breadcrumb_list>
</.breadcrumb>Custom separator
Replace the default / with any icon or character:
<.breadcrumb_separator>
<.icon name="chevron-right" size={:xs} />
</.breadcrumb_separator>Accessibility
- The
<nav>root carriesaria-label="breadcrumb"so screen readers announce it as a distinct landmark. - The current page
<span>carriesaria-current="page"so screen readers convey that the user is viewing this item. - Separators carry
aria-hidden="true"to avoid cluttering screen reader output with decorative punctuation. - The
<ol>element communicates order semantics to assistive technologies.
Summary
Functions
Renders the <nav aria-label="breadcrumb"> landmark wrapper.
Renders a … ellipsis to indicate that intermediate path segments have
been collapsed.
Renders a <li> wrapper for a single breadcrumb entry.
Renders a navigable ancestor link in the breadcrumb trail.
Renders the <ol> flex container that holds all breadcrumb items.
Renders the current page label — the last and non-interactive crumb.
Renders a breadcrumb separator between two items.
Functions
Renders the <nav aria-label="breadcrumb"> landmark wrapper.
This is the outermost container. Screen readers expose it as a named
navigation region distinct from the main navigation. Always place a
breadcrumb_list/1 inside.
Example
<.breadcrumb>
<.breadcrumb_list>
...
</.breadcrumb_list>
</.breadcrumb>Attributes
class(:string) - Additional CSS classes applied to the<nav>element. Defaults tonil.- Global attributes are accepted. HTML attributes forwarded to the
<nav>element (e.g.data-testid).
Slots
inner_block(required) - Should contain a singlebreadcrumb_list/1.
Renders a … ellipsis to indicate that intermediate path segments have
been collapsed.
Use this when the trail is too long to display in full (e.g. on mobile).
Typically wrapped in a breadcrumb_item/1:
<.breadcrumb_item>
<.breadcrumb_ellipsis />
</.breadcrumb_item>The ellipsis is aria-hidden="true" because it is purely decorative;
the hidden segments do not provide navigation value to screen reader users
in this collapsed state.
For accessible collapsible breadcrumbs, consider a <details> or a
phx-click toggle that expands hidden items on demand.
Attributes
class(:string) - Additional CSS classes applied to the ellipsis<span>. Defaults tonil.- Global attributes are accepted. HTML attributes forwarded to the
<span>element.
Renders a <li> wrapper for a single breadcrumb entry.
Each visible step in the trail should be wrapped in a breadcrumb_item/1.
Place breadcrumb_separator/1 directly inside breadcrumb_list/1 between
items — it renders as its own <li> and does not need to be inside an item.
Collapsing on mobile
Set collapse_on_mobile on middle items to hide them on small screens,
then add a breadcrumb_ellipsis/1 with class="sm:hidden" to indicate
hidden segments:
<.breadcrumb_item><.breadcrumb_link href="/">Home</.breadcrumb_link></.breadcrumb_item>
<.breadcrumb_separator />
<.breadcrumb_item collapse_on_mobile>
<.breadcrumb_link href="/products">Products</.breadcrumb_link>
</.breadcrumb_item>
<.breadcrumb_separator class={if @collapse, do: "hidden sm:list-item"} />
<.breadcrumb_item class="sm:hidden"><.breadcrumb_ellipsis /></.breadcrumb_item>
<.breadcrumb_separator class="sm:hidden" />
<.breadcrumb_item><.breadcrumb_page>Widget</.breadcrumb_page></.breadcrumb_item>Example
<.breadcrumb_item>
<.breadcrumb_link href="/products">Products</.breadcrumb_link>
</.breadcrumb_item>Attributes
collapse_on_mobile(:boolean) - Whentrue, addshidden sm:inline-flexto this breadcrumb item so it is hidden on mobile viewports and visible fromsm:breakpoint and wider. Apply this to middle items (not the first and last) to keep the breadcrumb trail compact on small screens. Pair with abreadcrumb_ellipsis/1that is only shown on mobile (class="sm:hidden") for a complete pattern.Defaults to
false.class(:string) - Additional CSS classes applied to the<li>element. Defaults tonil.Global attributes are accepted. HTML attributes forwarded to the
<li>element.
Slots
inner_block(required) - Abreadcrumb_link/1,breadcrumb_page/1, orbreadcrumb_ellipsis/1.
Renders a navigable ancestor link in the breadcrumb trail.
Provide either href for standard page navigation or navigate for
LiveView client-side navigation (avoids a full page reload). When both
are provided, href takes precedence.
The link shows a hover underline via hover:text-foreground hover:underline
to reinforce its interactive nature.
Example
<%!-- Standard href --%>
<.breadcrumb_link href="/dashboard">Dashboard</.breadcrumb_link>
<%!-- LiveView patch (pushes to browser history without reload) --%>
<.breadcrumb_link navigate="/projects/42">
My Project
</.breadcrumb_link>Attributes
href(:string) - Standard HTML href for the link URL. Defaults tonil.navigate(:string) - Phoenix LiveViewphx-navigatepath (client-side navigation without full page reload). Defaults tonil.class(:string) - Additional CSS classes applied to the<a>element. Defaults tonil.- Global attributes are accepted. HTML attributes forwarded to the
<a>element (e.g.target,rel).
Slots
inner_block(required) - Link text or content.
Renders the <ol> flex container that holds all breadcrumb items.
Uses flex-wrap so a long trail wraps gracefully on small screens.
The sm:gap-2.5 gap widens on larger viewports.
Example
<.breadcrumb_list>
<.breadcrumb_item>...</.breadcrumb_item>
<.breadcrumb_separator />
<.breadcrumb_item>...</.breadcrumb_item>
</.breadcrumb_list>Attributes
class(:string) - Additional CSS classes applied to the<ol>element. Defaults tonil.- Global attributes are accepted. HTML attributes forwarded to the
<ol>element.
Slots
inner_block(required) - Should containbreadcrumb_item/1andbreadcrumb_separator/1children.
Renders the current page label — the last and non-interactive crumb.
Unlike breadcrumb_link/1, this is a <span> (not a link) because the
user is already on this page. It carries aria-current="page" so screen
readers announce "Page, [label]" providing clear spatial context.
Styled text-foreground font-normal to visually distinguish it from
the muted-foreground ancestor links.
Example
<.breadcrumb_item>
<.breadcrumb_page>Billing</.breadcrumb_page>
</.breadcrumb_item>Attributes
class(:string) - Additional CSS classes applied to the<span>element. Defaults tonil.- Global attributes are accepted. HTML attributes forwarded to the
<span>element.
Slots
inner_block(required) - The current page name or label.
Renders a breadcrumb separator between two items.
Defaults to the / character. Supply a custom inner block to use a
different separator — for example a chevron-right icon:
<.breadcrumb_separator>
<.icon name="chevron-right" size={:xs} />
</.breadcrumb_separator>The separator is always aria-hidden="true" so screen readers do not
read decorative punctuation between each crumb.
Placement
Place breadcrumb_separator/1 directly inside breadcrumb_list/1,
between two breadcrumb_item/1 elements:
<.breadcrumb_list>
<.breadcrumb_item>...</.breadcrumb_item>
<.breadcrumb_separator /> <%!-- between items --%>
<.breadcrumb_item>...</.breadcrumb_item>
</.breadcrumb_list>Attributes
class(:string) - Additional CSS classes applied to the separator<li>. Defaults tonil.
Slots
inner_block- Custom separator content. When provided, overrides the default/character. Ideal for an icon component.