Fixing Next.js router query param returning undefined on initial render
Deepankar Bhade /
While building a React application using next.js, I stumbled upon an issue that kept me stuck for a good amount of time. I don't want people to do the same therefore I would be covering the fix in this blog. Feel free to skip to fix if you want to.
Issue
First, let's just try to reproduce this issue. You might encounter some cases where you need access to query params of a route. Nextjs makes it easy to deal with routes by using the useRouter hook. Here's an example code that you can place inside the /pages
directory to try it out.
import { useRouter } from 'next/router'; import React from 'react'; const Test = () => { const router = useRouter(); console.log(router.query); return <div>Hello World</div>; }; export default Test;
Now let's visit the router with some param and see the logs. In my case, I visited /test?name=Deepankar
.
{} {name: 'Deepankar'}
As you can see in the 1st render we don't have the access to the param. So how do we know when the router fields are updated client-side and ready for use?. Now let's look into the fix.
Fix
useRouter
hook returns isReady
field which is a boolean value that denotes if the router fields are updated client-side and ready for use. Accessing isReady
field should be done inside of useEffect
methods and not for conditionally rendering on the server.
import { useRouter } from 'next/router'; import React from 'react'; const Test = () => { const router = useRouter(); React.useEffect(() => { if (router.isReady) { // Code using query console.log(router.query); } }, [router.isReady]); return <div>Hello World</div>; }; export default Test;
Reason
Pages that are statically optimized by Automatic Static Optimization will be hydrated without their route parameters provided, i.e query
will be an empty object ({}
).
After hydration, Next.js will trigger an update to your application to provide the route parameters in the query
object.