* fix(middleware): preserve query params on rewrite
When middleware (or a `next.config.js` rewrite) sends a request to a new
target, vinext was throwing away the original request's query string,
breaking `getServerSideProps`/route-handler `query` for any URL of the
form `/rewrite-me?key=value`.
Match Next.js's behaviour:
`Object.assign(parsedUrl.query, rewrittenParsedUrl.query)` — keep the
original query first, let the rewrite-target's query win on key
conflicts. Applied to:
- middleware rewrites (middleware-runtime.ts)
- beforeFiles / afterFiles / fallback config rewrites (prod-server.ts,
index.ts, deploy.ts)
Closes#1342
References:
- https://github.com/vercel/next.js/blob/canary/packages/next/src/server/route-modules/route-module.ts (Object.assign merge)
- https://github.com/vercel/next.js/blob/canary/test/e2e/edge-pages-support/index.test.ts (rewrite query expectations)
* test(query): document URL-encoded space normalization on rewrite merge
Addresses Bonk review observations on #1375:
- Add test confirming `%20` → `+` normalization through URLSearchParams
is intentional and lossless (downstream consumers re-parse).
- Drop unreachable `?? ""` fallback in mergeRewriteQuery; `String#split`
always yields a string.
* fix: stabilize instrumentation state and hydration E2E tests
Move Cloudflare instrumentation example state from module-level
variables to globalThis so startup and request paths share one owner
across different module instances.
Add waitForHydration() helper to Pages Router E2E tests to eliminate
flaky button-click assertions that raced against React hydration.
* fix: honor the `as` parameter in router.push/replace
The `as` parameter in push() and replace() was silently ignored
(prefixed as _as) in both the useRouter() hook and the Router
singleton. This broke masked URLs and legacy dynamic-route flows.
Extract resolveNavigationTarget() helper that uses `as` when provided,
falling back to resolveUrl(url) otherwise. Apply to all four call
sites: useRouter().push, useRouter().replace, Router.push, Router.replace.
* fix: address PR review feedback
- Add doc comment to resolveNavigationTarget explaining the url/as
simplification vs Next.js's two-value approach
- Extract waitForHydration to shared tests/e2e/helpers.ts
- Add pathname assertion to verify router.pathname stays as route
pattern (/posts/[id]) after as-based navigation
* fix: remove pathname assertion that tests unimplemented behavior
router.pathname currently returns the resolved path after client-side
navigation, not the route pattern. The correct behavior (returning
/posts/[id] instead of /posts/42) requires the two-value url/as
approach tracked in #462.