Commit Graph

4 Commits

Author SHA1 Message Date
James Anderson 81c0b03ef2 fix(pages): preserve not-found response headers (#2773)
* fix(pages): preserve not-found response headers

* fix(pages): preserve not-found headers in dev
2026-08-03 15:59:22 +01:00
James Anderson bc586788a2 fix(middleware): preserve query params on rewrite (#1375)
* 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.
2026-05-21 11:38:52 +01:00
Nathan Nguyen 45b72eade5 fix: honor the as parameter in router.push/replace (#453)
* 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.
2026-03-11 09:00:27 +00:00
Steve Faulkner 12fea722b6 Initial public release of vinext 2026-02-24 09:29:39 -06:00