APG Patterns
日本語
日本語

Breadcrumb

A navigation pattern that shows the user's current location within a site hierarchy.

Demo

Basic Breadcrumb

A simple breadcrumb trail showing the path to the current page.

Long Path

A deeper navigation path with multiple levels of hierarchy.

Open demo only →

Accessibility Features

WAI-ARIA Roles

RoleTarget ElementDescription
navigation<nav> elementProvides a navigation landmark for assistive technology (implicit role of <nav>)

WAI-ARIA Properties

aria-label

Labels the navigation landmark for screen readers

Values
Breadcrumb (or localized)
Required
Yes

aria-current

Identifies the current page within the breadcrumb trail

Values
page
Required
Yes (on last item)

WAI-ARIA States

aria-current

Target Element

Last item in the breadcrumb (current page)

Values
page
Required
Yes
Change Trigger

Indicates the current page location within the breadcrumb navigation.

Keyboard Support

KeyAction
TabMove focus between breadcrumb links
EnterActivate the focused link
  • Breadcrumb uses native <a> element behavior for keyboard interaction. No additional keyboard handlers are required.

References

Source Code

Breadcrumb.astro
---
/**
 * Breadcrumb component following WAI-ARIA APG pattern
 * @see https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/
 */

export interface BreadcrumbItem {
  label: string;
  href?: string;
}

export interface Props {
  items: BreadcrumbItem[];
  ariaLabel?: string;
  class?: string;
}

const { items, ariaLabel = 'Breadcrumb', class: className } = Astro.props;
---

{
  items.length > 0 && (
    <nav aria-label={ariaLabel} class:list={['apg-breadcrumb', className]}>
      <ol class="apg-breadcrumb-list">
        {items.map((item, index) => {
          const isLast = index === items.length - 1;
          return (
            <li class="apg-breadcrumb-item">
              {item.href && !isLast ? (
                <a href={item.href} class="apg-breadcrumb-link">
                  {item.label}
                </a>
              ) : (
                <span aria-current={isLast ? 'page' : undefined} class="apg-breadcrumb-current">
                  {item.label}
                </span>
              )}
            </li>
          );
        })}
      </ol>
    </nav>
  )
}

Usage

Example
---
import Breadcrumb from './Breadcrumb.astro';

const items = [
  { label: 'Home', href: '/' },
  { label: 'Products', href: '/products' },
  { label: 'Current Product' }
];
---

<Breadcrumb items={items} />

API

Prop Type Default Description
items BreadcrumbItem[] required Array of breadcrumb items
ariaLabel string "Breadcrumb" Accessible label for the navigation
class string - Additional CSS class

Testing

Tests verify APG compliance across ARIA attributes, semantic structure, and accessibility requirements. The Breadcrumb component uses a two-layer testing strategy.

Testing Strategy

Unit Tests (Testing Library)

Verify the component's rendered output using framework-specific testing libraries. These tests ensure correct HTML structure and ARIA attributes.

  • HTML structure (nav, ol, li elements)
  • ARIA attributes (aria-label, aria-current)
  • Link rendering and href values
  • Accessibility via jest-axe

E2E Tests (Playwright)

Verify component behavior in a real browser environment across all frameworks. These tests cover interactions and cross-framework consistency.

  • Keyboard navigation (Tab, Enter)
  • ARIA structure in live browser
  • axe-core accessibility scanning
  • Cross-framework consistency checks

Test Categories

High Priority: APG ARIA Attributes

TestDescription
nav elementUses semantic <nav> element
aria-labelNavigation has accessible label (default: "Breadcrumb")
aria-current="page"Last item has aria-current="page"
ol/li structureUses ordered list for proper semantic structure

High Priority: Keyboard Interaction

TestDescription
Tab navigationTab moves focus between breadcrumb links
Enter activationEnter key activates focused link
Current page not focusableLast item (span) is not in tab order

Medium Priority: Accessibility

TestDescription
axe violationsNo WCAG 2.1 AA violations (via jest-axe)
Custom aria-labelCan override default label via ariaLabel prop
Separator hiddenVisual separators are hidden from assistive technology

Low Priority: Component Behavior

TestDescription
Renders all itemsAll provided items are rendered in order
Links have hrefNon-current items render as links with correct href
className mergeCustom classes are merged with component classes

Low Priority: Cross-framework Consistency

TestDescription
All frameworks have navReact, Vue, Svelte, Astro all render breadcrumb navigation
Same item countAll frameworks render the same number of breadcrumb items
Current page markedAll frameworks mark the last item with aria-current="page"

Testing Tools

See testing-strategy.md (opens in new tab) for full documentation.

Resources