The Next.js team built a powerful router component, next/router. I’m not a fan (more on that at the end). It seems they followed the conventions of the already mythical React Router, but more adapted to Next.js and its features. Its API is very easy though, but it encourages relying on it for application state. Through sweat and pain I found again and again that it’s a bad idea.
Simple scenarios are okay
Imagine we have a blog app and we have a page like
/blog/[postSlug].tsx for URLs like
We get the slug like this:
This example is fine. Blog posts are not very dynamic anyway. How frequently is a user expected to change blog post? Not that quickly.
Scenarios with fast changing state and SSR aren’t okay
However, when changing the URL too frequently between routes that have SSR, weird things can start to happen. The route change triggers a request to the server on each change and produces a re-render of the app (which can be expensive performance-wise).
As a real world example, in After Memorials users can swipe through the timeline quite rapidly, and each photo in the timeline has a unique URL associated.
If we updated the URL in each swipe, we’d quickly start seeing errors like these:
Error: Cancel rendering route
Error: Loading initial props cancelled
Also, app performance would slow down during route changes, especially when doing animations.
Solution: keep state in context/Redux and sync it to the URL after
Don’t rely on the router’s
query for rendering the application. Instead, keep your state where it should be, inside a
useState or Redux.
Then, use an effect to sync the state to the URL with a debounce, so that it will update only after there are no more changes.
useKeepBrowserPathUpdated where your application state is.
In any case, I’m not a fan of
next/router. For example:
router.queryfor both the URL query params and the dynamic route parameters?
Why the result of
useRoutercan change on renders? It forces us to use the undocumented global export
import Router from 'next/router'in order to do
Still, I’m very grateful to all developers for creating Next.js. It’s so good to work with it and it’s exciting to see how it’s evolving (thank you!).