Hash Link Routing for React Applications
When working on a client web application earlier this year I needed to support a common navigation implementation. The users would need to be able to navigate directly to an element on a page using hash link routing.
My team and I were leveraging react router to handle our page navigation. After doing some research I reached for the most popular npm package I could find, react-router-hash-link
.
This package surfaces some components to be used as an alternative to react-router-dom
components such as Link
and NavLink
. The replacement components allow the user to navigate directly to elements on the page if the path specified in the value of the to
property includes a hash fragment and the target element has in id
identical to the hash fragment value. There is a stipulation that you must be using react router's BrowserRouter
to take advantage of this package which was fine with us because that's exactly what we were using.
However, for our use case, I quickly found that the flagship scroll-to-element functionality wasn't working as needed in the following circumstances:
- Browser forward/back operation to a URL with a hash fragment
- Opening a URL with a hash fragment in a new tab
- Page refresh
To my surprise this seemingly common problem was disappointingly not fully solved. Don't get me wrong, react-router-hash-link
is a completely valid solution for many use cases. Unfortunately, there were too many unsupported features for our use case.
At this point I had taken a look at a few popular packages in hopes that one would "just work". However, I ended up having to hand-roll the solution to fit our customer's needs. Using inspiration from react-router-hash-link
and this blog post I created react-hash-link
.
react-hash-link
works in all of the following situations from the README.
- Navigating to a URL with a hash fragment and corresponding element on the page
- Opening qualifying URLs/pages in a new browser tab or window
- Forward browser navigation
- Backward browser navigation
- Page reload
- Works with
react-router
but not dependent on it - Works with server-side rendering
- All of the above scenarios function correctly when used across all major browsers (including IE)
Check out the differences between these packages by comparing a sample app using react-router-hash-link
and the same app using react-hash-link
.