3

I have a component inside a page in a dynamic route in Next.js that needs to read the URL query string parameters. The app has a collection of articles you can search, and you can get to a specific 'page' within the article by visiting the appropriate URL.

So I have a pages route like so in the file structure:

/pages -> /article -> /[articleId] -> [pageNum].tsx

[pageNum].tsx is SSR-enabled, i.e. it contains a getServerSideProps function.

When the user performs a search, the search parameters are kept in the query string i.e. ?q=something&order=date.... However, in the component in question if I do the following:

const router = useRouter();

useEffect(() => {
  if (!router.isReady) return;
  console.log(router.query);
}, [router]);

All I see in the console is the pathname parameters, and not the query string params. So if I visit:

.../123/456?q=something&order=date

The logged out query object is only ever:

{ articleId: 'something', pageNum: '456' }

This means that when we create a 'Back' button that retains the query string parameters, the URL we return to has unrecognised values in it and any applied filters are lost. Fundamentally I'm missing some valuable piece of information - why do the query string parameters not come through?

Logging out the router object outside a useEffect shows this:

asPath: "/article/article_100000/2?q=iceland"
back: ƒ ()
basePath: ""
beforePopState: ƒ ()
components: {/article/[articleId]/[pageNum]: {…}, /_app: {…}, /search/[start]/[size]: {…}}
defaultLocale: undefined
domainLocales: undefined
events: {on: ƒ, off: ƒ, emit: ƒ}
isFallback: false
isLocaleDomain: false
isPreview: false
isReady: true
locale: undefined
locales: undefined
pathname: "/article/[articleId]/[pageNum]"
prefetch: ƒ ()
push: ƒ ()
query:
  pageNum: "2"
  articleId: "article_100000"
[[Prototype]]: Object
reload: ƒ ()
replace: ƒ ()
route: "/article/[articleId]/[pageNum]"

It's possible to take the asPath property and shave bits off it to get what's needed but I don't understand why the query object doesn't have what I need.

6
  • Is it like that only for the first render? are you using router from nextjs or react? Commented Dec 15, 2021 at 17:56
  • It seems to happen on every render for if I take the log out out useEffect the console in the browser repeatedly logs the same object with the pathname params. It's the nextjs router. Commented Dec 15, 2021 at 18:08
  • Can you add to the question what you get when you do console.log(router) Commented Dec 15, 2021 at 18:11
  • Added more logging Commented Dec 15, 2021 at 23:35
  • @mattlock did you find a solution for this? I'm having the same problem. Commented Apr 13, 2022 at 9:04

1 Answer 1

4

Late for the reply but still -

router has a variable isReady which remains false when rendered from the server side, which is the first load. From the next load onwards it becomes true and starts providing query.

So to use this, we will have to apply useEffect

const router = useRouter();
React.useEffect(() => {
    if (router.isReady) {
        // Code using query
        console.log(router.query);
    }
}, [router.isReady]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.