I saw a tweet recently from Heydon Pickering that offered commentary on a web development topic someone made on Reddit.
“Switch between two pages on the client side within a multi page website?”
“I have no idea but I feel like it should be easy. Trivial. Perhaps even built into browsers themselves. You could have an HTML element specifically for it. One starting with ‘a’ perhaps, so it is easy to find.”
While it is a bit snarky, it made me chuckle. There’s definitely truth to Heydon’s sentiment.
If for some reason you must use client-side routing, using a library like React Helmet (or similar scripting functionality) to make changes to the document
If client-side routing libraries try to guess for us and move focus to the same place for every situation, it can lead to a sub-par experience. This is why libraries have largely punted on addressing accessibility in client-side routing. To solve this, we need routing APIs that allow us tap into navigation events and handle focus management and announcements gracefully.
I ran into this recently while building out the Mega Nav component for the Testing Accessibility demo application. When testing menu interactivity and navigation, I found that client-side navigation with Reach Router wasn’t properly resetting the menu state while simultaneously jumping focus too far down the page automatically. Adding some code to reset menu state was an easy enough fix, but APIs for managing focus left more to be desired. In this case, using the trusty <a> tag instead of a special <Link> component allowed the browser to take care of both issues itself.
While it depends on the type of application you’re building, my general suggestion for the moment is to let pages refresh if you can. Doing this ensures that the focus point is reset, and that Assistive Technology users aren’t left wondering if anything happened. This practice will still play nicely with the dynamic updates from React Helmet, too.
There are a lot of accessibility wins we can get for free from the HTML elements we choose and the browsers the render them. It’s just a matter of knowing what to look for.