What Routing Breaks, and How to Fix It

The problem nobody mentions. A normal page load tells assistive technology that a new page arrived: focus resets, the title is announced, the screen reader starts from the top.

A client-side navigation does none of that. The URL changes, the content changes, and as far as a screen reader is concerned nothing happened at all. Focus is still sitting on the link that was just clicked, which no longer exists.

What to do about it. Two things, both small.

Move focus to the new page's main heading after a route change, using a ref and focus(). Give that heading tabIndex={-1} so it can receive focus without becoming a tab stop.

Update document.title, so the tab, the history and the window switcher all say something meaningful.

This is the most commonly skipped requirement in single page applications, and it is perhaps twenty lines for a whole app.

Try it

Remove tabIndex={-1} and try again. focus() silently does nothing, because a heading is not focusable by default.

loading editor…

loading React…

Switch pages and watch the focus ring land on the heading. That ring is the visible half of what a screen reader announces.

Mark this lesson complete

Signed in, your progress follows you to every device.

Next: Practice Test →
← Back