Skip to content

fix(a11y): add skip-to-main-content link for keyboard users - #1115

Merged
zeekman merged 1 commit into
zeekman:mainfrom
godekina:fix/navbar-skip-link-1052
Jul 30, 2026
Merged

fix(a11y): add skip-to-main-content link for keyboard users#1115
zeekman merged 1 commit into
zeekman:mainfrom
godekina:fix/navbar-skip-link-1052

Conversation

@godekina

Copy link
Copy Markdown
Contributor

Summary

Closes #1052.

  • Adds a "Skip to main content" link as the first focusable element on every page, visually hidden until focused (new frontend/src/accessibility.css), targeting the existing shared <main id="main-content"> landmark that every route already renders into (AppContent in App.jsx) - so criterion 2 (a main-content landmark to target) was already satisfied app-wide, no per-page changes needed there.
  • Gave that <main> tabIndex={-1} and an explicit onClick on the skip link that calls .focus() on it directly, rather than relying solely on the browser's native "focus the fragment target" behavior - that behavior is inconsistent across browsers for non-natively-focusable elements even with tabindex, so this makes the focus move deterministic.

Unrelated but blocking: frontend/src/components/Navbar.jsx on main has a botched merge left in - two duplicate import ... from 'react' statements (a hard SyntaxError, duplicate binding) and three overlapping/unclosed <nav> openings stacked on top of each other, one of them referencing an unimported Link component. The file cannot compile as it stands on main, so this PR also deduplicates it down to the single intended nav structure (NavLink brand with active-route styling, network badge, hamburger + drawer, focus trap) - kept as minimal as possible, no behavior changes beyond making it valid again.

Test plan

  • New frontend/src/test/SkipToMainContent.test.jsx: skip link is the first Tab stop ahead of every nav link, activating it moves focus to #main-content, link carries the visually-hidden-until-focus class
  • frontend/src/test/NavbarActiveRoute.test.jsx (pre-existing) passes again now that Navbar.jsx compiles
  • pnpm exec vitest run - no new failures introduced (16 pre-existing failures elsewhere in the suite, e.g. api.getOrdersStreamUrl is not a function, confirmed present on unmodified main too, unrelated to this change)

…ifact

Adds a "Skip to main content" link as the first focusable element on
every page, visually hidden until focused, targeting the existing
shared <main id="main-content"> landmark that every route already
renders into. Gives that landmark tabIndex={-1} plus an explicit
onClick focus call, since relying only on native browser fragment-focus
behavior for a non-interactive element is inconsistent across browsers.

Navbar.jsx on main had a botched merge left in place: two duplicate
`import ... from 'react'` statements (a hard SyntaxError - duplicate
binding) and three overlapping, unclosed <nav> openings stacked
together, one of them using an unimported `Link` component. The file
could not have compiled. Deduplicated down to the single intended nav
structure (NavLink brand with active-route styling, network badge,
hamburger + drawer, focus trap) so the app - and this fix - can
actually build.

Closes zeekman#1052
@drips-wave

drips-wave Bot commented Jul 30, 2026

Copy link
Copy Markdown

@godekina Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@zeekman
zeekman merged commit 15a33e3 into zeekman:main Jul 30, 2026
2 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Navbar has no 'skip to main content' link for keyboard users

2 participants