Skip to content
Folio

Navigation

Breadcrumb

Where you are, as a path.

Usage

TSX
import { Breadcrumb } from '@misoto22/design'

Notes

Where you are, as a path.

The last crumb is plain text with aria-current="page" rather than a link to itself — a self-link is the most common breadcrumb bug, and it makes a screen reader offer a navigation that goes nowhere.

Separators live in <li aria-hidden> so the trail is read as its items and not as "home slash work slash".

A middle crumb with no href is a defect that is invisible twice over: it renders as plain text in the same --ink-3-aa as the links beside it, and it carries no aria-current either — so it reads as the page the reader is on when it is not, and neither the browser nor a review says a word. The console does, in development.

Anatomy

Breadcrumb anatomy
ElementDescription
TrailrequiredA <nav> named by label, which defaults to “Breadcrumb”. It is a landmark whether or not the page wanted another one, set in mono-meta at --ink-3-aa.
ListrequiredAn <ol> — the order is the hierarchy, not the reader’s history. It wraps rather than truncating, so a deep path takes a second line instead of losing a level.
Crumb linkAn <a> for every item that has an href and is not the last. The label is a ReactNode, so whatever you put in it becomes part of the link’s accessible name.
Current crumbrequiredThe last item, always: plain text at full --ink with aria-current="page", whether or not it was given an href.
SeparatorA slash by default, in its own <li aria-hidden> between crumbs. Decorative by construction — it is never part of what is read out.

Best practices

Do

  • Pass label when a page can hold two trails: both nav landmarks are named “Breadcrumb” otherwise, and two landmarks with one name are two entries a reader cannot choose between.
  • Give every crumb but the last an href — one without renders as plain text in the same colour as the links beside it, with no destination and no aria-current, so it reads as the page the reader is on when it is not. Development names the crumb rather than leaving an omission that is invisible in the browser and in review.
  • Start the trail above the current page: a one-item Breadcrumb renders that item as the current crumb with no path at all, which is a landmark announcing a journey of length one.

Don’t

  • Leave the href off the last item rather than passing one it ignores: the last crumb is text whatever you hand it, so an href there reads as a link in review and is not one at run time.
  • Do not hide it on a phone to save a line. That is the layout where the sidebar is behind a drawer, which makes the trail the only way up a level that is on the screen.

Examples

default

Where you are, as a path. The last crumb is plain text carrying aria-current="page" and never a link to itself — a self-link is the most common breadcrumb bug, and it offers a screen reader a navigation that goes nowhere. The separators sit in their own aria-hidden list items, so the trail is read as its items rather than as home slash components slash. label names the nav landmark; a page that can hold two trails has to name both, or a reader gets two entries called Breadcrumb and no way to choose.

a deep path

A path deep enough to wrap, with a separator that is not the default slash. The list wraps rather than truncating, and that is the right trade: the level a truncating trail drops is usually the one the reader was heading for. The separator is decorative whatever is put in it — it lives in an aria-hidden list item and is never read out. Do not hide this on a phone to save a line. That is the layout where the sidebar is behind a drawer, which makes the trail the only way up a level that is on the screen at all.

page header

The trail above the title it ends on. Start it above the current page: a one-item Breadcrumb renders that item as the current crumb with no path at all, which is a landmark announcing a journey of length one. Every crumb but the last needs an href — one without renders as plain text in the same colour as the links beside it, with no destination and no aria-current, so it reads as the page the reader is on when it is not. The last crumb repeating the heading is not a duplication to fix: one is the path, the other is the page.

Invoice 2024-118

Issued 4 March, due 3 April. Unpaid.

Accessibility

  • The last crumb is text with aria-current="page", never a link to itself.
  • Separators are aria-hidden, so the trail is not read as “home slash work slash”.
  • A middle crumb with no href takes no aria-current and no colour of its own, which is why the omission is reported in development instead of shipped as a crumb that impersonates the current page.