Breadcrumb
A navigation pattern that shows the user's current location within a site hierarchy.
🤖 AI Implementation GuideDemo
Basic Breadcrumb
A simple breadcrumb trail showing the path to the current page.
Long Path
A deeper navigation path with multiple levels of hierarchy.
Accessibility Features
WAI-ARIA Roles
| Role | Target Element | Description |
|---|---|---|
navigation | <nav> element | Provides a navigation landmark for assistive technology (implicit role of <nav>) |
WAI-ARIA Breadcrumb Pattern (opens in new tab)
WAI-ARIA Properties
| Attribute | Target | Values | Required | Description |
|---|---|---|---|---|
aria-label | <nav> | "Breadcrumb" (or localized) | Yes | Labels the navigation landmark for screen readers |
aria-current | Current page element | "page" | Yes (on last item) | Identifies the current page within the breadcrumb trail |
WAI-ARIA States
aria-current="page"
Indicates the current page location within the breadcrumb navigation.
| Target | Last item in the breadcrumb (current page) |
| Values | "page" |
| Required | Yes |
| Reference | aria-current (opens in new tab) |
Keyboard Support
| Key | Action |
|---|---|
| Tab | Move focus between breadcrumb links |
| Enter | Activate the focused link |
Breadcrumb uses native <a> element behavior for keyboard interaction. No additional
keyboard handlers are required.
Source Code
Breadcrumb.vue
<script setup lang="ts">
/**
* 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 BreadcrumbProps {
items: BreadcrumbItem[];
ariaLabel?: string;
class?: string;
}
const props = withDefaults(defineProps<BreadcrumbProps>(), {
ariaLabel: 'Breadcrumb',
});
function getItemKey(item: BreadcrumbItem): string {
return `${item.href ?? 'current'}-${item.label}`;
}
</script>
<template>
<nav v-if="items.length > 0" :aria-label="ariaLabel" :class="['apg-breadcrumb', props.class]">
<ol class="apg-breadcrumb-list">
<li v-for="(item, index) in items" :key="getItemKey(item)" class="apg-breadcrumb-item">
<a
v-if="item.href && index !== items.length - 1"
:href="item.href"
class="apg-breadcrumb-link"
>
{{ item.label }}
</a>
<span
v-else
:aria-current="index === items.length - 1 ? 'page' : undefined"
class="apg-breadcrumb-current"
>
{{ item.label }}
</span>
</li>
</ol>
</nav>
</template> Usage
Example
<script setup>
import Breadcrumb from './Breadcrumb.vue';
const items = [
{ label: 'Home', href: '/' },
{ label: 'Products', href: '/products' },
{ label: 'Current Product' }
];
</script>
<template>
<Breadcrumb :items="items" />
</template> API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | BreadcrumbItem[] | required | Array of breadcrumb items |
ariaLabel | string | "Breadcrumb" | Accessible label for the navigation |
BreadcrumbItem
| Property | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Display text for the item |
href | string | No | URL for the link (omit for current page) |
Testing
Tests verify APG compliance across ARIA attributes, semantic structure, and accessibility requirements.
Test Categories
High Priority: APG ARIA Attributes
| Test | Description |
|---|---|
nav element | Uses semantic <nav> element |
aria-label | Navigation has accessible label (default: "Breadcrumb") |
aria-current="page" | Last item has aria-current="page" |
ol/li structure | Uses ordered list for proper semantic structure |
High Priority: Keyboard Interaction
| Test | Description |
|---|---|
Tab navigation | Tab moves focus between breadcrumb links |
Enter activation | Enter key activates focused link |
Current page not focusable | Last item (span) is not in tab order |
Medium Priority: Accessibility
| Test | Description |
|---|---|
axe violations | No WCAG 2.1 AA violations (via jest-axe) |
Custom aria-label | Can override default label via ariaLabel prop |
Separator hidden | Visual separators are hidden from assistive technology |
Low Priority: Component Behavior
| Test | Description |
|---|---|
Renders all items | All provided items are rendered in order |
Links have href | Non-current items render as links with correct href |
className merge | Custom classes are merged with component classes |
Testing Tools
- Vitest (opens in new tab) - Test runner for unit tests
- Testing Library (opens in new tab) - Framework-specific testing utilities (React, Vue, Svelte)
- Playwright (opens in new tab) - Browser automation for E2E tests
- axe-core/playwright (opens in new tab) - Automated accessibility testing in E2E
See testing-strategy.md (opens in new tab) for full documentation.
Resources
- WAI-ARIA APG: Breadcrumb Pattern (opens in new tab)
- MDN: Breadcrumb Navigation (opens in new tab)
- AI Implementation Guide (llm.md) (opens in new tab) - ARIA specs, keyboard support, test checklist