We recently announced the second major release of Gatsby 🚀. One change we want to highlight is the switch to using @reach/router to improve the accessibility of routing in Gatsby sites. What is @reach/router, and what are the benefits of undertaking the switch?
What is @reach/router?
@reach/router is a routing library for React written and maintained by one of the original creators of react-router, Ryan Florence. After investigating the tradeoffs, we made the leap to depending on @reach/router:
- Accessibility is a first-class concern
- Smaller bundle size (~70% decrease, 18.4kb to 6kb gzipped)
- Simplified API
How does it support accessibility?
When you visit a Gatsby site, a static, server-rendered HTML page is loaded first, and then the JavaScript to hydrate the site into a web app is loaded. From there, internal routing is handled with the Gatsby Link component, which wraps @reach/router’s Link component.
Web apps rerender in the client — without making a request to the server to fetch new HTML — resulting in a faster, more seamless user experience. These performance benefits, however, can create a broken experience for users who rely on assistive technology like screen readers.
When a user navigates between traditional server-rendered pages, the page is fully reloaded; In response, screen readers can announce the new content. When using most client-side routing solutions (out of the box), without the page reload, screen readers don’t know new content has been loaded to focus or announce.
The video below demonstrates this challenge (Video by Rob DeLuca, which accompanied his related article, “Single page app routers are broken”)
A primary focus (no pun intended) of @reach/router is to manage focus in client-side routing, out of the box, lifting the onus from devs to manage it from scratch. From the @reach/router documentation:
Whenever the content of a page changes in response to a user interaction, the focus should be moved to that content; otherwise, users on assistive devices have to search around the page to find what changed–yuck! Without the help of a router, managing focus on route transitions requires a lot effort and knowledge on your part.
Reach Router provides out-of-the-box focus management so your apps are significantly more accessible without you breaking a sweat.
When the location changes, the top-most part of your application that changed is identified and focus is moved to it. Assistive devices then announce to the user the group of elements they are now focused on, similarly to how it works when they load up a page for the first time.
The video below demonstrates this focus management:
Check out that focus management 😍
— Ryan Florence (@ryanflorence) May 31, 2018
The same code that makes this possible is what makes relative links and embedded routers possible too. pic.twitter.com/DjqveMfspA
In terms of the development experience with Gatsby, this change is mostly under the hood, folded into the implementation of the Gatsby Link component. In terms of usability, accessibility by default is a win for everyone 🙌🏻.
Migrating from v1 ➡️ v2
For most sites, migrating from v1 to v2 shouldn’t be too painful, but there are a few instances you might want to be aware of. Check out the v2 migration guide for details.
TLDR;
Smaller package + better accessibility + simplified APIs 👍
We look forward to continuing to work actively with Ryan!
Reach Router is hitting the big time with @gatsbyjs adopting it and Nike shipping a site with it https://t.co/fthOUQ1lJh :D
— Ryan Florence (@ryanflorence) September 18, 2018
I'll be spending all day Thursday fixing/adding stuff Gatsby needs. AND! Gatsby is sponsoring my time.
Thanks @kylemathews and the rest of the team 🙏🏽
Related Gatsby docs:
External references:
- Single page app routers are broken by Rob DeLuca
- @reach/router docs