next.js
next.js copied to clipboard
request.url is incorrect and inconsistent when NextResponse.rewrite() is used
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:17:10 PDT 2022; root:xnu-8020.140.49~2/RELEASE_X86_64
Binaries:
Node: 16.13.1
npm: 8.19.1
Yarn: 1.22.17
pnpm: N/A
Relevant packages:
next: 12.3.1-canary.3
eslint-config-next: 12.3.0
react: 18.2.0
react-dom: 18.2.0
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
next dev, Vercel
Describe the Bug
When NextResponse.rewrite(newUrl)
is called, we expect the value of newUrl
to consistently be reflected inside request.url
for the new URL's handler.
Instead, the value of request.url
is inconsistent depending on the environment (dev vs prod) and the runtime (node vs edge).
The table below details the current behavior:
Development | Production | ||
Edge ✅ | Node ❌ | Edge ❌ | Node ❌ |
request.url is set to the new URL passed to rewrite() |
request.url is set to the original URL |
request.url is set to the pathname of the original URL and the query string of the new URL passed to rewrite() |
Note: this table holds for both API routes and React pages
Expected Behavior
We haven't found any documentation of the intended behavior.
We would expect request.url
in the endpoint to always reflect the URL passed to rewrite. If not, it feels like it hasn't been rewritten.
Link to reproduction
https://github.com/clerkinc/nextjs-middleware-debugging
To Reproduce
The readme in the linked repository includes commands to quickly reproduce every scenario
The steps to rebuild the repo are:
- Build and host endpoints for each permutation (dev and prod, node and edge). In each endpoint, log the value of
request.url
- Build middleware to rewrite a request to that endpoint. When you rewrite, make sure to include a query param since they are part of what behaves inconsistently.
- run a request that triggers your middleware rewrite, then check what the logs to see what
request.url
was set to