amannn/next-query-params

Query params are present on the server during SSG with dynamic routes

Opened this issue · 3 comments

Describe the bug

When using dynamic routes with SSG, query parameters appear to be present when rendering on the server, but they shouldn't be. Since they are present on the server, but not present on the initial render once mounted on the client, it causes a hydration conflict.

edit: issue is also present in static pages in development mode (since development mode always runs getStaticProps)

To Reproduce

CodeSandbox: https://codesandbox.io/p/sandbox/angry-hamilton-4qj68g

Steps to reproduce the behavior:

  1. Add a query parameter called test with any value to the preview page (e.g. ?test=1).
  2. See error
    image

Also looking at the logs generated on the server side, you'll see that the query parameter is present in the use-query-params' useQueryParam(s) calls, but not present in the nextjs router's router.query.

Expected behavior

Query parameters should not be present when rendering dynamic routes on the server.

In a brief test, replacing

return {search: router.asPath.replace(pathnameRegex, '')} as Location;
with

search: new URLSearchParams(router.query).toString()

appears to fix it, but it'll also include route parameters (e.g. /path/[param].ts -> { param: 'valueinurl' }), which could potentially be a breaking change, since route params seem to have precedence over query params.

amannn commented

Hmm, I see. I guess it could be a reasonable change nonetheless.

If you're up to testing this a bit further, feel free to open a PR with the change! We have some existing tests that could help to verify this.

We should be sure that this works with SSR the way it did previously, maybe we can add tests to verify SSG/SSR behavior.

This is not only an issue with dynamic routes, but with any page that has a getStaticProps export. Just rename the [[...slug]].tsx file in your CodeSandbox to index.tsx, remove the getStaticPaths export, and try reproducing. You will see the same error.