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

Make router.query available from any route, regardless of data fetching requirements. #20026

Closed
acalvino4 opened this issue Dec 9, 2020 · 7 comments

Comments

@acalvino4
Copy link

acalvino4 commented Dec 9, 2020

Feature request

To access query parameters (i.e. ?author=Nick&category=lifestyle) in a page route in next.js, the appropriate method seems to be getting a router reference via the useRouter hook. However, the documentation notes that router.query "will be an empty object during prerendering if the page doesn't have data fetching requirements". Would it be possible to do away with this requirement? Is there any reason that a route without getStaticProps or getServerSideProps can't have access to these params, given that they are typically accessible from window.location? I think implementing this would improve the user experience.

Of note, the router object returned from useRouter already has access to these params in it's asPath attribute. I may be missing something, but it would seem trivial to me to have a method that loads these into the router.query object from the useRouter() call.

Describe alternatives

The alternative seems to be implementing getStaticProps or getServerSideProps, though besides this being more work than is ideal from a developer experience perspective, there aren't really instructions on how exactly this is accomplished. Does just having getStaticProps implemented then load params into router.query? Or do I need to pass context.params from getServerSideProps in as a prop? So far I haven't figured out how this alternative works either.

@jamesmosier
Copy link
Contributor

Hi @acalvino4. There are a number of issues like this (that I can't track down right now), but I did find this answer to be descriptive of what the reasoning is: #16019 (comment)

@acalvino4
Copy link
Author

Hi @jamesmosier, thank you for pointing me to that discussion.

I'm still a little confused, as this paragraph from that discussion:

Now let's say every single one of your visitors uses a different query param. What's happening in that case is that we will continue to serve the same exact html page (that didn't know anything about the query params when it was created) and once the JS executes in the browser you can start making dynamic changes to the page. That's why there's no way to know your query params unless the page is generated per-request

implies to me that while at initial load the query params are of course unknown, that useRouter could still have client side code that is executed to read in the query params and update the page from there - is that correct?

@timneutkens
Copy link
Member

implies to me that while at initial load the query params are of course unknown, that useRouter could still have client side code that is executed to read in the query params and update the page from there - is that correct?

But only after hydration https://reactjs.org/docs/react-dom.html#hydrate as otherwise the html content does not match up with the client-side hydration React tree and React will throw away all the pre-rendered content causing performance issues. If you don't have getStaticProps or getServerSideProps Next.js will automatically statically generate the page, meaning the HTML does not change after build.

When a hydration mismatch happens it causes UI jumps which is worse for user experience.

I'll close this issue as there's multiple others already like #8259

@hexetia
Copy link

hexetia commented Dec 12, 2020

@acalvino4 I just published a package with a workaround

It's a tiny package that wrap the next.js router to provide the router.query and router.pathname on client-side first render

https://www.npmjs.com/package/use-client-router

@timneutkens
Copy link
Member

@morhogg as said in #20026 (comment) providing it is not the way to go and will cause performance issues and jumps in your application.

@acalvino4
Copy link
Author

acalvino4 commented Jan 3, 2021

@timneutkens @jamesmosier There are a few points in my original post that were not really answered yet.

  1. "the router object returned from useRouter already has access to these params in it's asPath attribute. I may be missing something, but it would seem trivial to me to have a method that loads these into the router.query object from the useRouter() call." - Why is this not possible?
  2. Ultimately, I do trust your judgement as someone familiar with the codebase, so I am interested in best practice workarounds. If it really is impossible to ever implement this feature, then we can refocus the discussion to a request to have more clear documentation about the alternative. In my original post I described what is lacking in the documentation currently.

@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 28, 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

5 participants