Skip to main content

Skip-to-content link present

ab-002586 · project-snapshot.accessibility.skip-to-content-link
Severity: lowactive

Why it matters

Keyboard-only users — including everyone using a screen reader, voice control, or a switch device — land on each new page at the top of the DOM and must Tab through the full header, nav, and any cookie banner before they reach the actual content. On a typical marketing site that is 15–40 tab stops per page. A skip link, hidden via sr-only but revealed on focus, collapses that to a single keystroke. AI coding tools almost never emit one by default because scaffolds like create-next-app omit it and model training data treats it as an optional polish rather than a layout primitive, so generated app/layout.tsx files ship without it. The failure mode this check catches is not "site is inaccessible" but "site is exhausting to navigate without a mouse" — which is the more common lived experience for users on WCAG 2.4.1 ("Bypass Blocks").

Severity rationale

Low because the absence of a skip link slows keyboard navigation rather than blocking it, and WCAG 2.4.1 is satisfied by any equivalent bypass mechanism (ARIA landmarks, proper heading structure) most codebases already have in place.

Remediation

Add to your root layout:

<a href="#main-content" className="sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4">
  Skip to main content
</a>
<main id="main-content">{children}</main>

Deeper remediation guidance and cross-reference coverage for this check lives in the accessibility-fundamentals Pro audit — run that after applying this fix for a more exhaustive pass on the same topic.

Detection

  • ID: project-snapshot.accessibility.skip-to-content-link
  • Severity: low
  • What to look for: Check the root layout (app/layout.tsx, pages/_app.tsx, app/_layout.tsx) for a <a href="#main-content"> (or similar #main/#content/#skip) link near the top of the body. The link should be visually-hidden but focusable (sr-only focus:not-sr-only or equivalent).
  • Pass criteria: A skip link exists in the root layout pointing to the main content landmark.
  • Fail criteria: No skip link found.
  • Skip (N/A) when: Project has no global layout (purely SSG with per-page layouts and no shared shell).
  • Do NOT pass when: A skip link exists but the target ID (#main-content etc.) is not actually present anywhere in the layout.
  • Report even on pass: "Skip link found in {layout file}: <a href='#main-content'>...; target landmark exists: yes."
  • Detail on fail: "No skip-to-content link found in app/layout.tsx or equivalent root layout".
  • Remediation: Add to your root layout:
    <a href="#main-content" className="sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4">
      Skip to main content
    </a>
    <main id="main-content">{children}</main>
    

Taxons

History