Skip to content
easeweb
Search topics

Single-page app route changes that are never announced

A single-page app's router swaps in the new view and updates the title, but leaves focus where it was, so nothing is said and the next Tab starts from the old place.

WCAG 2.2
SC 2.4.3ASC 4.1.3AA· new in 2.1
Required by
Section 508 · EN 301 549 (EU)
Broken
The accessibility problem illustrated: The view changed. Focus stayed behind on the link.
01

The problem

Screen reader users hear nothing when a link changes the view, and keyboard users carry on from a place that no longer leads anywhere.

02

Try it

Tab to a link in the shop, press Enter, and listen.

Try a link in the header, then the link at the end of the list. After each, press Tab once: where does focus go next?

Broken Can you fix this?

Teas – Harbor Tea

Teas

  • Assam, 100 g
  • Sencha, 100 g
  • Earl Grey, 100 g

Shop teaware

Screen reader says:

(Press Enter on a link)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

After each route change, move focus to the new view's heading, or to the top of the page with a spoken page name.

  1. 1After each route change, move focus on purpose: to the new heading, or to the top with an announcement.
  2. 2Say the new view's name once, through focus or a status region that was there from the start.
  3. 3Leave focus alone on the first load and on changes within one view.
Before The router sets the title and nothing else
<body>  <nav>    <a href="/teas">Teas</a>    <a href="/teaware">Teaware</a>    <a href="/basket">Basket</a>  </nav>  <main id="view">    <h1>Teaware</h1>    …  </main></body>
After

Focus the new view's heading

<body>  <nav>    <a href="/teas">Teas</a>    <a href="/teaware">Teaware</a>    <a href="/basket">Basket</a>  </nav>  <main id="view">    <h1 tabindex="-1">Teaware</h1>    …  </main></body>

Fixing this with an AI coding assistant? Get this guide as Markdown

04

Verify the fix

5 checks, no mouse.

Test with: Keyboard, Screen reader, Zoom

0 of 5 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat when the router or the layout changes.

Limits

This is a starting pattern, not a guarantee for every application. Screen readers react differently to focus on a heading and to focus on the body, so test with the ones your users use. This guide covers views that replace the main content. Dialogs, drawers and in-page updates have their own patterns. Test the complete journey on your real routes, including deep links and slow networks.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

Keep this fixed as your code changes.

Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.

How retests work