Navigation Documentation Index: For an overview of all navigation documentation, see NAVIGATION_GUIDE_INDEX.md
Overview
Breadcrumbs provide hierarchical navigation context, helping users understand their location within the application and navigate back to parent pages. Encore OS uses a unified breadcrumb system with:- Desktop: Auto-generated breadcrumbs in the header (
DesktopHeader+Breadcrumbs) - Mobile: Same trail as desktop in the fixed context row under the primary
MobileHeaderrow (MobileBreadcrumbs). Do not render a second duplicate trail in page bodies when the shell already shows crumbs. - Centralized policy:
shouldShowBreadcrumbs/shouldShowMobileHeaderContextRowinsrc/platform/navigation/utils/breadcrumb-visibility.ts(keepResponsiveNavmainpadding-topaligned with whether the context row is visible). - Shared segment logic:
src/platform/navigation/utils/generate-route-breadcrumb-segments.ts(desktop and mobile use the same generator). - Centralized Labels: All route labels in
route-labels.ts
Mobile placement contract
- When
shouldShowBreadcrumbs(pathname)is true, breadcrumbs appear only inMobileHeader’s second row (not inside scrollablemain). PageContainerbreadcrumbs+showBreadcrumbsrender only when the header policy is false for that route (avoids duplicate chrome). Prefer fixing policy/labels over in-page duplicates.- Two-segment module routes that still need crumbs (e.g.
/ce/referral-sources,/cl/pdmp) are allowlisted inbreadcrumb-visibility.ts(MODULE_TWO_SEGMENT_BREADCRUMB_ROUTES). - Never mount
<Breadcrumbs />inside page content; useuseBreadcrumbLabel/useEntityBreadcrumbfor dynamic last segments.
Quick Reference
Basic Implementation
Desktop (Auto-generated):Common Patterns
Adding Custom Label:- Open
src/platform/navigation/route-labels.ts - Add entry to
BASE_ROUTE_LABELS:'/route/path': 'Display Label'(Title Case) - Breadcrumbs automatically use the label
npm run audit:routes-navigationenforces 100% coverage — every<Route>must have a label
- Default shows last 2 segments
- Adjust with
maxSegmentsprop - Horizontal scroll for overflow
- Desktop:
@/platform/navigation/Breadcrumbs.tsx - Mobile:
@/platform/navigation/MobileBreadcrumbs.tsx - Labels:
@/platform/navigation/route-labels.ts
1. Architecture
Component Structure
Data Flow
- User navigates to a route (e.g.,
/hr/employees/123/edit) Breadcrumbs.tsxparses the pathname into segments- Each segment is looked up in
ROUTE_LABELS - Breadcrumb trail is rendered with links to parent routes
Breadcrumb Flow Diagram
2. Component Reference
2.1 Base Primitives (@/shared/ui/breadcrumb)
2.2 Auto-Generated (@/platform/navigation/Breadcrumbs.tsx)
Automatically generates breadcrumbs based on the current route path. Used in DesktopHeader.
Features:
- Parses pathname into segments
- Looks up labels in
ROUTE_LABELS - Handles module context
- Falls back to formatted path segments
2.3 Mobile (@/platform/navigation/MobileBreadcrumbs.tsx)
Mobile-optimized breadcrumbs with truncation and scroll.
Props:
Features:
- Shows last N segments
- Horizontal scroll for overflow
- 44px touch targets
- Safe area support
2.4 Route Labels (@/platform/navigation/route-labels.ts)
Centralized map of route paths to display labels. Keys are full URL paths
starting with /. The map currently contains ~1,140 entries covering every
declared <Route> in src/routes/*.tsx — npm run audit:routes-navigation
enforces this coverage and exits non-zero if any route is missing a label.
2.5 Hub Tab Labels (@/platform/navigation/hub-tab-labels.ts)
For tabbed-hub pages that pass the active tab via ?tab=, the breadcrumb
appends the tab label as the trailing segment (e.g.
HR > Recruiting > Candidates). The map supports both literal hub paths
(/hr/ats) and parameterized paths (/cl/charts/:chartId,
/pm/patients/:patientId) via single-segment wildcard matching.
2.6 Dynamic entity labels (@/shared/lib/hooks/useEntityBreadcrumb)
The preferred way to set the trailing crumb to an entity name (e.g.
employee full name, invoice number, claim ID) on detail pages.
useBreadcrumbLabel(label), which sets the label
for the current location.pathname in BreadcrumbContext and clears it on
unmount. Both desktop and mobile breadcrumbs then render the entity name in
place of the static ROUTE_LABELS value for that path.
Coverage check: npm run audit:breadcrumb-coverage lists detail pages
that don’t yet set a dynamic label so they can be migrated. Add new
detail pages to this pattern by default.
3. Implementation Patterns
Pattern 1: Auto-Generated (Recommended)
When to use: Most pages where route structure matches breadcrumb trail.Pattern 2: Dynamic entity name via useEntityBreadcrumb (preferred for detail pages)
When to use: Detail/edit pages with a :id segment where the trailing
crumb should be the entity name (employee, invoice, patient, etc.).
Pattern 3: Explicit PageContainer breadcrumbs (fallback)
When to use: Pages that need a custom trail not derivable from the route
(e.g. wizards, multi-step flows, two-segment pages outside the auto-show
policy). For most routes the header already auto-renders the trail and
PageContainer suppresses the inline copy — so prefer Pattern 1 or 2.
⛔ Anti-pattern: importing breadcrumb primitives directly in pages
Do not import@/shared/ui/breadcrumb primitives in core or feature
pages. The shadcn primitives are reserved for PageContainer,
Breadcrumbs.tsx, and MobileBreadcrumbs.tsx. Pages should only ever rely
on:
- The auto-generated header trail (Pattern 1)
useEntityBreadcrumb/useBreadcrumbLabelfor dynamic entity names (Pattern 2)PageContainer breadcrumbs={[…]} showBreadcrumbsfor custom trails (Pattern 3)
4. Adding New Routes
When creating new features, add route labels toBASE_ROUTE_LABELS in
route-labels.ts. Keys are full URL paths starting with /; values are
Title Case.
Naming Conventions
Fallback Behavior
If a route is not inROUTE_LABELS, the system:
- Takes the path segment (e.g.,
work-orders) - Replaces hyphens with spaces
- Capitalizes the first letter of each word
- Result: “Work Orders”
Always add an explicit label rather than relying on the fallback —
audit:routes-navigation enforces 100% coverage.
Two-segment leaf pages (e.g. /ce/referral-sources)
By default shouldShowBreadcrumbs hides crumbs on two-segment module
routes (/{core}/{page}), since the ModuleSwitcher already conveys
module context. If a particular two-segment leaf page still benefits from
the trail (e.g. /ce/referral-sources, /cl/pdmp), add it to
MODULE_TWO_SEGMENT_BREADCRUMB_ROUTES in
src/platform/navigation/utils/breadcrumb-visibility.ts.
5. Mobile Considerations
MobileBreadcrumbs Integration
Mobile breadcrumbs are automatically included inMobileHeader:
Truncation Behavior
Touch Targets
All breadcrumb links MUST have:- Minimum 44x44px touch area
- Adequate spacing (8px minimum between items)
- Visual feedback on touch
6. Accessibility
Required Attributes
<nav aria-label="Breadcrumb">on container<ol>for breadcrumb list (semantic ordering)aria-current="page"on current page item
Keyboard Navigation
- All links must be focusable
- Tab order follows visual order
- Focus indicators must be visible
Screen Readers
The breadcrumb structure announces:- “Breadcrumb, navigation”
- Each link in order
- “Current page: [Page Name]” for last item
7. Testing Checklist
Unit Tests
- Route parsing generates correct segments
-
ROUTE_LABELSlookup returns expected values - Fallback formatting works correctly
- Module context is handled
Integration Tests
- Breadcrumbs update on navigation
- Links navigate to correct routes
- Mobile truncation works at breakpoints
Accessibility Tests
- Screen reader announces structure correctly
- Keyboard navigation works
- Focus indicators visible
Visual Tests
- Desktop breadcrumbs render correctly
- Mobile breadcrumbs truncate properly
- Touch targets meet 44px requirement
- Safe areas respected on mobile
8. Common Mistakes & Anti-Patterns
❌ Importing breadcrumb primitives in pages
❌ Detail page without a dynamic label
Run npm run audit:breadcrumb-coverage to see which detail pages still
need this migration.
❌ Duplicate “Back to X” link alongside breadcrumbs
❌ Forgetting to add route labels
❌ Inconsistent label format
❌ Breadcrumbs on module dashboards
❌ Page H1 doesn’t match breadcrumb tail
9. Quick Reference
When to Show Breadcrumbs
File Locations
Audits
Related Documentation
Standards
- Constitution §6.3.1 - Breadcrumb standards and requirements
Navigation Guides
- Mobile Navigation Guide - Section 12: Mobile Breadcrumb Patterns
- Navigation Guide Index - Complete navigation documentation index
- Navigation Standard - Navigation patterns and policies
External References
- shadcn/ui Breadcrumb - Component reference