DEV Community

Cover image for Fixing Next.js router query param returning undefined on initial render
Deepankar Bhade
Deepankar Bhade

Posted on • Originally published at dpnkr.in

Fixing Next.js router query param returning undefined on initial render

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

Now let's visit the router with some param and see the logs. In my case, I visited /test?name=Deepankar.

{}
{name: 'Deepankar'}
Enter fullscreen mode Exit fullscreen mode

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

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.

References:

Discussion (7)

Collapse
codedog001 profile image
Mohit

I was stuck at this line:
if (!router.isReady) {
return;
}
for a lot of time, the page kept crashing. When I saw your code, it immedeately clicked in my mind, why not do the thing when router.isReady.
Thank you so much! It was lifesaver.

Collapse
deepcodes profile image
Deepankar Bhade Author

I am so glad for this.

This exactly why I wrote this blog. Awesome

Collapse
ben888github profile image
Benedict Ryan

Thanks dude, it helps!

Collapse
brewpy profile image
Brewpy App

How to do it for SSR pages?

Collapse
codedsalis profile image
Salisu Ibn Alli

No need to use it for SSR pages. In your getServerSideProps, there's a context parameter that returns the route query. You can get it by calling context.params.query where query is the query parameter. e.g: www.example.com?q=what+is+your+name
q in the URL above is the query parameter

Collapse
suhakim profile image
sadiul hakim

Nice

Collapse
zigang93 profile image
Tan Zi Gang

HI, what's your next.js version?
Currently, I am using the nextjs 12.1.5
I cannot reproduce the issue..