Accessibility in React apps
🏠The everyday picture
A lift that announces each floor and has braille buttons. It takes little extra effort at installation, and a lot of effort to add later.
📘What it really is
Everything from Modules 12, 13 and 35, plus the problems single-page apps add:
-
Page changes are silent. When the router changes the screen, screen readers may not notice. Update the page title on each route, and move focus to the new page's main heading.
-
Focus management: after opening a dialog, focus goes inside it; after closing, it returns to the button that opened it. Use the native
<dialog>element or a well-tested library. -
Dynamic updates: announce results with
role="status"(polite) orrole="alert"(urgent). - Icon-only buttons need a name:
<button aria-label="Delete enquiry">. - Automated checks find about a third of problems:
- Lighthouse (Module 12);
- eslint-plugin-jsx-a11y warns while you code;
-
axe in tests (
vitest-axeorjest-axe). -
Then test by hand: keyboard only, 200% zoom, and a screen reader (NVDA on Windows, VoiceOver on Mac and iPhone, TalkBack on Android).
🖱️Try it
Make each page set document.title and focus its <h1> on arrival (give it tabIndex={-1} so it can receive focus).
Add an axe check to two of your component tests. Then use your phone's screen reader to add an enquiry from start to
finish, and fix the first problem you find.
✅Quick check
Why move focus to the heading after a route change?
Show the answer
Otherwise screen-reader users may not know the page changed, and keyboard users start from the wrong place.
Lighthouse gives 100 for accessibility. Is the app fully accessible?
Show the answer
Not necessarily. Automated tools find only some problems; test with a keyboard and a screen reader too.
