
Navigation Landmark
- 1 installs
- 73.4k repo stars
- Updated June 18, 2026
- thedaviddias/frontendchecklist
Verifies navigation areas use nav elements with distinguishing aria-labels and wraps navigation links accordingly for screen reader landmarks.
About
Checks that navigation regions use nav elements with aria-label so screen reader users can jump between navigation areas by landmark. A developer uses it when reviewing templates or shared components for accessible markup.
- Wrap nav links in nav elements with descriptive aria-labels
- Provide skip links to bypass repetitive navigation
Navigation Landmark by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,914 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedaviddias/frontendchecklist --skill navigation-landmarkAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 73.4k |
| Last updated | June 18, 2026 |
| Repository | thedaviddias/frontendchecklist ↗ |
What it does
Verifies navigation areas use nav elements with distinguishing aria-labels and wraps navigation links accordingly for screen reader landmarks.
Files
Use navigation landmark regions
Navigation landmarks allow screen reader users to quickly jump to and identify different navigation areas—without them, users must tab through every link to find what they need.
Quick Reference
- Wrap navigation links in nav elements
- Use aria-label to distinguish multiple nav regions
- Provide skip links to bypass repetitive navigation
- Screen reader users navigate by landmarks
Check
Verify navigation areas use nav elements with aria-label or aria-labelledby to distinguish primary, secondary, and footer navigation.
Fix
Wrap navigation links in nav elements with descriptive aria-labels like 'Main navigation' or 'Footer navigation'.
Explain
Explain how navigation landmarks help screen reader users quickly identify and jump to different navigation areas.
Code Review
Review templates, server-rendered HTML, and shared components that output markup related to Use navigation landmark regions. Flag exact elements, attributes, and routes where the rendered HTML violates the rule.
---
For full implementation details, code examples, and framework-specific guidance, see references/rule.md.
Rule page: https://frontendchecklist.io/en/rules/html/navigation-landmark
Use navigation landmark regions
Page navigation uses nav elements with proper ARIA labels to distinguish multiple navigation regions.
Priority: high · Difficulty: beginner · Time: 15 min
--- Navigation landmarks help users understand page structure and quickly jump to different navigation sections.
Code Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<body>
<!-- Skip link (first element) -->
<a href="#main-content" class="skip-link">
Skip to main content
</a>
<header>
<!-- Primary navigation -->
<nav aria-label="Main">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<!-- Breadcrumb navigation -->
<nav aria-label="Breadcrumb">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/products/widgets" aria-current="page">Widgets</a></li>
</ol>
</nav>
<main id="main-content">
<!-- Page content -->
<!-- In-page navigation (table of contents) -->
<nav aria-label="Table of contents">
<h2>On this page</h2>
<ul>
<li><a href="#section-1">Section 1</a></li>
<li><a href="#section-2">Section 2</a></li>
<li><a href="#section-3">Section 3</a></li>
</ul>
</nav>
<h1>Page Title</h1>
<section id="section-1">...</section>
<section id="section-2">...</section>
<section id="section-3">...</section>
</main>
<aside>
<!-- Sidebar navigation -->
<nav aria-label="Related pages">
<h2>Related</h2>
<ul>
<li><a href="/related-1">Related Page 1</a></li>
<li><a href="/related-2">Related Page 2</a></li>
</ul>
</nav>
</aside>
<footer>
<!-- Footer navigation -->
<nav aria-label="Footer">
<ul>
<li><a href="/privacy">Privacy Policy</a></li>
<li><a href="/terms">Terms of Service</a></li>
<li><a href="/sitemap">Sitemap</a></li>
</ul>
</nav>
</footer>
</body>
</html>Why It Matters
Navigation landmarks allow screen reader users to quickly jump to and identify different navigation areas—without them, users must tab through every link to find what they need.
Navigation Landmark Types
| Region | Element | aria-label Example |
|---|---|---|
| Main navigation | <nav> | "Main navigation" |
| Secondary navigation | <nav> | "Secondary navigation" |
| Footer navigation | <nav> | "Footer navigation" |
| Breadcrumb | <nav> | "Breadcrumb" |
| Pagination | <nav> | "Pagination" |
| Table of contents | <nav> | "Table of contents" |
React Navigation Components
interface NavLinkProps {
href: string
children: React.ReactNode
isCurrent?: boolean
}
function NavLink({ href, children, isCurrent }: NavLinkProps) {
return (
<li>
<a
href={href}
aria-current={isCurrent ? 'page' : undefined}
>
{children}
</a>
</li>
)
}
interface MainNavProps {
links: Array<{ href: string; label: string }>
currentPath: string
}
return (
<nav aria-label="Main">
<ul className="main-nav">
{links.map(link => (
{link.label}
))}
</ul>
</nav>
)
}
interface BreadcrumbProps {
items: Array<{ href: string; label: string }>
}
return (
<nav aria-label="Breadcrumb">
<ol className="breadcrumb">
{items.map((item, index) => {
const isLast = index === items.length - 1
return (
<li key={item.href}>
{isLast ? (
<span aria-current="page">{item.label}</span>
) : (
<>
<a href={item.href}>{item.label}</a>
<span aria-hidden="true"> / </span>
</>
)}
</li>
)
})}
</ol>
</nav>
)
}
interface FooterNavProps {
sections: Array<{
title: string
links: Array<{ href: string; label: string }>
}>
}
return (
<nav aria-label="Footer">
<div className="footer-nav">
{sections.map(section => (
<div key={section.title} className="footer-nav__section">
<h3>{section.title}</h3>
<ul>
{section.links.map(link => (
<li key={link.href}>
<a href={link.href}>{link.label}</a>
</li>
))}
</ul>
</div>
))}
</div>
</nav>
)
}Skip Links
return (
<div className="skip-links">
<a href="#main-content" className="skip-link">
Skip to main content
</a>
<a href="#main-nav" className="skip-link">
Skip to navigation
</a>
<a href="#search" className="skip-link">
Skip to search
</a>
</div>
)
}.skip-link {
position: absolute;
top: -40px;
left: 0;
padding: 8px 16px;
background: #000;
color: #fff;
z-index: 1000;
transition: top 0.2s;
}
.skip-link:focus {
top: 0;
}Next.js Layout Example
// app/layout.tsx
children
}: {
children: React.ReactNode
}) {
const navLinks = [
{ href: '/', label: 'Home' },
{ href: '/products', label: 'Products' },
{ href: '/about', label: 'About' },
{ href: '/contact', label: 'Contact' },
]
const footerSections = [
{
title: 'Company',
links: [
{ href: '/about', label: 'About Us' },
{ href: '/careers', label: 'Careers' },
]
},
{
title: 'Legal',
links: [
{ href: '/privacy', label: 'Privacy Policy' },
{ href: '/terms', label: 'Terms of Service' },
]
}
]
return (
<html lang="en">
<body>
<header>
</header>
<main id="main-content">
{children}
</main>
<footer>
</footer>
</body>
</html>
)
}When to Use aria-labelledby vs aria-label
<!-- aria-label: Short, simple label -->
<nav aria-label="Main">
<!-- No visible heading -->
</nav>
<!-- aria-labelledby: Reference visible heading -->
<nav aria-labelledby="footer-nav-heading">
<h2 id="footer-nav-heading">Quick Links</h2>
<ul>...</ul>
</nav>Common Mistakes
<!-- ❌ Multiple nav without labels -->
<nav>...</nav>
<nav>...</nav>
<!-- ✓ Labeled navigation regions -->
<nav aria-label="Main">...</nav>
<nav aria-label="Footer">...</nav>
<!-- ❌ Using div instead of nav -->
<div class="navigation">...</div>
<!-- ✓ Semantic nav element -->
<nav aria-label="Main">...</nav>
<!-- ❌ Nesting nav elements -->
<nav>
<nav>...</nav>
</nav>
<!-- ✓ Separate nav regions -->
<nav aria-label="Primary">...</nav>
<nav aria-label="Secondary">...</nav>Verification
1. Use screen reader landmark navigation (NVDA: D key, VoiceOver: rotor) 2. Verify each nav region has unique label 3. Check skip link appears on focus 4. Verify aria-current on current page link 5. Test keyboard navigation through all links 6. Confirm nav count matches expected regions
Use nav elements only for major navigation blocks. Minor link groups (like social media icons) don't need to be navigation landmarks. Too many landmarks reduces their usefulness.