Navigation System
The navigation system is composed of three layers: menu data (configuration), header navigation (primary + utility + mobile), and footer navigation. Each layer is independently configurable.
Architecture
src/site/config/menus.ts ← SITE-OWNED menu data
src/core/components/layout/Header.astro ← primary + utility + mobile nav
src/core/components/layout/Footer.astro ← footer nav columns
Menu data is defined in src/site/config/menus.ts and consumed by both the header and footer. Components do not hardcode link lists — all navigation content flows from configuration.
Menu Configuration (DOC-00003)
Menus are defined as typed arrays in menus.ts. Each entry specifies a label, href, and optional children for dropdown support. See Menu Configuration for the full schema and dropdown behavior.
Header Navigation (DOC-00011)
The Header component renders three navigation zones:
- Primary nav — main site sections, rendered as a horizontal link list on desktop
- Utility nav — secondary actions (e.g., login, CTA button), right-aligned
- Mobile nav — collapsible drawer triggered by the hamburger button
The active page link is highlighted via aria-current="page" set at render time based on the current URL. See Header & Navigation for props and slot usage.
Footer Navigation (DOC-00012)
The Footer component renders multi-column link groups sourced from the footer menu configuration. Column headings and link lists are data-driven. See Footer Navigation for column configuration and theming.
Skip Navigation
A visually hidden “Skip to main content” link is rendered by the SkipLink component (part of BaseLayout) and appears on keyboard focus. It targets #main-content — all page layouts must include an element with that id.
Accessibility
- All nav elements use
<nav>with a uniquearia-labelto distinguish them from each other in the accessibility tree - Mobile nav toggle uses
aria-expandedandaria-controlswired to the drawer element - Keyboard navigation within dropdowns follows the disclosure pattern (Enter/Space to open, Escape to close)
- Focus is trapped within the mobile drawer when open; closing restores focus to the hamburger button