Remix is the newest hottest full-stack React framework. Remix supports file-based routing which uses react-router-dom
under the hood which is a popular react routing library.
Because Remix users react-router's BrowserRouter internally, you can't actually do Hash Routing (id based routing that triggers scrolling) with it.
For example, if you create a link like this,
<Link to="#footer">
Go to bottom
</Link>
it will surely change the browser URL, but won't scroll down to the element with an id of footer.
Of course, there's an easier way to achieve this behavior.
Turning off Client-Side Routing
We can add a reloadDocument
prop to the specialized Link component and it will start acting like a normal anchor tag.
<Link to="#footer" reloadDocument>
Go to bottom
</Link>
This in turns, turns off client-side routing and lets the browser handle the transition, as mentioned here
This is fine until you want both client-side routing and scroll behavior on hash routing.
Manual Scrolling via Side-Effect
The workaround this is to catch the side-effect created by the route change inside a useEffect
and handle the scrolling manually.
In the root (root.jsx file) of our projects, we have to get the location object from the useLocation
hook provided by remix. Then, we have to create a useEffect which depends on that location object. The location object has a property called hash which provides us with the hash portion of the URL e.g. #footer if the URL is www.example.com/#footer. Then we can look up the element containing that id and manually scroll down to it using the scrollIntoView
method.
const location = useLocation();
useEffect(() => {
if (location.hash) {
const el = document.querySelector(location.hash);
if (el) {
el.scrollIntoView();
}
}
}, [location]);
Top comments (0)