Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router.query is empty on subsequent client navigation events #9473

Closed
derekdowling opened this issue Nov 20, 2019 · 15 comments
Closed

Router.query is empty on subsequent client navigation events #9473

derekdowling opened this issue Nov 20, 2019 · 15 comments
Assignees
Milestone

Comments

@derekdowling
Copy link

Bug report

Describe the bug

Using Next 9's routing solution for a Universal App, "router.query" for post-SSR client-side navigation is never populated even if asPath contains a query string for any of the following
router access methods:

import { SingletonRouter, useRouter, withRouter } from 'next/router';

To Reproduce

Perform an initial navigation to /search?term=hello, the server rendered page's router information contains a populated "query":

const router = useRouter();
console.log({ router }); // asPath: "/search?term=hello", pathname: "/search", query: { term: "hello" }

Then navigate to the same pathname, with a different query string: /search?term=bye. At this point Router empties "query", but has the correct new asPath:

const router = useRouter();
console.log({ router }); // asPath: "/search?term=hello", pathname: "/search", query: {}

Expected behavior

For the client side navigation to a route with specified query parameters such as /search?term=bye, router.query contains the parsed query string.

If this is not expected, it would be helpful to better document this behavior and the correct approach on the client. I would prefer to always access routing information off of the available hook / HOC rather than off window on the client to avoid a split-brain solution between the client and the server.

@ijjk
Copy link
Member

ijjk commented Nov 20, 2019

Hi, for the query to be populated you must provide it to the href value not just the asPath. It does look like this needs to be updated in our docs to better explain this so thanks for bringing that to our attention!

@Timer Timer added this to the 9.1.x milestone Nov 20, 2019
@derekdowling
Copy link
Author

derekdowling commented Nov 20, 2019

Oh, that would explain the behavior we are seeing 👍 We were effectively doing:

<Link href={pathname} as={pathname + '?' + query} />

@cybervaldez
Copy link

Hi, for the query to be populated you must provide it to the href value not just the asPath. It does look like this needs to be updated in our docs to better explain this so thanks for bringing that to our attention!

Hi, I used your solution and it works when i'm listening to the query change in my hook but it doesn't seem to be parsed within router events (routeChangeComplete)
#9574 (comment)

@Pashozator
Copy link

@ijjk thank you, it helped me.

@VladDubrovskis
Copy link

Is there an example of how this would work with router.push instead of a Link?
Been trying to work this one out but so far no luck. For now, just doing the parsing of asPath parameter but that does not feel optimal

@timneutkens
Copy link
Member

Router.push(href, as) is the signature, it works in the same way as <Link>

So:

Router.push('/abc?hello=123', '/abc?hello=123')

@VladDubrovskis
Copy link

@timneutkens If you path first parameter as a full path it will make a hard refresh instead of client-side update, which goes around the issue but not necessarily fixing it.

Example I have is in line with docs, with dynamic paths:

Router.push('/post/[pid]', '/post/abc')}

@timneutkens
Copy link
Member

Works in the same way as the earlier reply:

Router.push('/post/[pid]?hello=123', '/post/abc?hello=123')}

@VladDubrovskis
Copy link

Aaaah, href is the first parameter so needs to have query parameres - it finally clicked and works as expected now :) Thanks @timneutkens ❤️

@somratAtSekaiLab
Copy link

This will work for single or multiple query params as well dynamic routing:

const query = { param1: 'foo', param2: 'bar' }

const url = { pathname: '/search/[id]', query };

const urlAs = { pathname: '/search/1234', query }

router.push(url, urlAs);

Output:

/search/1234?param1=foo&param2=bar

@mehulmpt
Copy link

mehulmpt commented Aug 9, 2020

I believe this is a relevant issue #16019

@lfades
Copy link
Member

lfades commented Sep 16, 2020

I don't think this is an issue anymore, our docs have been updated and we added more clear examples for the usage of next/link.

For client side navigations you have to provide the query parameters required by the page, and if a page is statically generated you should only try to read the query parameters after hydration (i.e inside useEffect) because when we generate the page we don't know anything about the query parameters or hash, or anything else more than the path of the page, with the exceptions of:

  • Static pages with getStaticPaths will get the query parameter that is used for that page populated. E.g /blog/[post].js might have { query: { post: 'my-post' } } populated if getStaticPaths defines my-post in the returned list of paths.
  • Pages that use getServerSideProps have access to the query before hydration because the page is generated per-request in a serverless function, instead of at build time.

If any of the above behaviors doesn't match what you currently have on your application (or our docs do a bad job) feel free to comment it out again with a reproduction and I'll re open the issue. Thank you.

@lfades lfades closed this as completed Sep 16, 2020
@Timer Timer removed this from the 9.x.x milestone Sep 16, 2020
@Timer Timer added this to the iteration 9 milestone Sep 16, 2020
@stefanprobst
Copy link
Contributor

i think the docs could maybe add some clarification to here. i've written down my understanding of this in this discussion

@rojvv
Copy link
Contributor

rojvv commented Oct 18, 2021

Many confusion, still existing.

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests