DEV Community

Cover image for Hash routing in Remix!
Zul Ikram Musaddik Rayat
Zul Ikram Musaddik Rayat

Posted on

Hash routing in Remix!

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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]);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)