Skip to content

Add opt-in next routing resolver delegation#94102

Draft
timneutkens wants to merge 1 commit into
codex/server-routing/result-mapperfrom
codex/server-routing/opt-in-delegation
Draft

Add opt-in next routing resolver delegation#94102
timneutkens wants to merge 1 commit into
codex/server-routing/result-mapperfrom
codex/server-routing/opt-in-delegation

Conversation

@timneutkens
Copy link
Copy Markdown
Contributor

@timneutkens timneutkens commented May 25, 2026

What?

Adds an opt-in live server delegation path from resolve-routes.ts to @next/routing behind __NEXT_EXPERIMENTAL_USE_NEXT_ROUTING_RESOLVER=1. The guard intentionally limits delegation to compatible production requests and falls back to the legacy resolver for dev, minimal mode, upgrade requests, i18n, basePath, trailingSlash, middleware, exportPathMap, RSC requests, and dynamic filesystem route apps.

This also adds @next/routing as a next package dependency, ensures isolated tests pack the local @next/routing package, and fixes repeated destination query parameters in @next/routing so rewrites like /?items=1&items=2 preserve array values.

Why?

This is the first live-server adoption step after the audit, adapter input builder, and result mapper PRs. It keeps default behavior unchanged while making it possible to exercise selected production route-resolution paths through the shared package. Existing routing e2e coverage showed dynamic Pages Router behavior is not equivalent enough yet, so this PR keeps those apps on the legacy resolver until dedicated dynamic-route equivalence work lands.

How?

  • Build @next/routing state from the existing fsChecker adapter.
  • Convert Node request headers and URL state into the package resolver input.
  • Map resolved package results back into the live resolveRoutes result shape.
  • Return delegated results only when the package resolver actually finished or matched an output; otherwise continue through the legacy resolver.
  • Skip delegation for dynamic route apps so static asset priority, data-route cache keys, and dynamic client navigation stay on the proven live path.

Verification

  • pnpm --filter @next/routing test
  • pnpm testonly test/unit/server-routing-equivalence/next-routing-adapter.test.ts test/unit/server-routing-equivalence/resolve-routes.test.ts
  • pnpm --filter @next/routing build
  • pnpm --filter=next build
  • __NEXT_EXPERIMENTAL_USE_NEXT_ROUTING_RESOLVER=1 NEXT_TEST_PREFER_OFFLINE=1 pnpm test-start-turbo test/e2e/rewrites-has-condition/rewrites-has-condition.test.ts test/e2e/rewrites-destination-query-array/rewrites-destination-query-array.test.ts test/e2e/dynamic-routing/dynamic-routing.test.ts
  • __NEXT_EXPERIMENTAL_USE_NEXT_ROUTING_RESOLVER=1 NEXT_TEST_PREFER_OFFLINE=1 pnpm test-start-turbo test/e2e/trailingslash-with-rewrite/index.test.ts test/e2e/i18n-support-index-rewrite/i18n-support-index-rewrite.test.ts test/e2e/app-dir/rsc-query-routing/rsc-query-routing.test.ts test/e2e/middleware-rewrites/test/index.test.ts
  • __NEXT_EXPERIMENTAL_USE_NEXT_ROUTING_RESOLVER=1 NEXT_TEST_PREFER_OFFLINE=1 pnpm test-dev-turbo test/development/gssp-redirect-with-rewrites/gssp-redirect-with-rewrites.test.ts test/development/dynamic-route-rename/dynamic-route-rename.test.ts test/development/trailing-slash-dist/trailing-slash-dist.test.ts
  • __NEXT_EXPERIMENTAL_USE_NEXT_ROUTING_RESOLVER=1 NEXT_TEST_PREFER_OFFLINE=1 pnpm test-start-turbo test/production/rewrite-request-smuggling/rewrite-request-smuggling.test.ts test/production/standalone-mode/required-server-files/required-server-files.test.ts -t "does not smuggle|should resolve correctly when a redirect is returned|should handle data routes with optional catch-all params|should de-dupe HTML/data requests"
  • git diff --check

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

Failing test suites

Commit: 19ecc5b | About building and testing Next.js

pnpm test-start-turbo test/production/next-server-nft/next-server-nft.test.ts (turbopack) (job)

  • next-server-nft > with output:standalone > should not trace too many files in next-server.js.nft.json (DD)
Expand output

● next-server-nft › with output:standalone › should not trace too many files in next-server.js.nft.json

expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `next-server-nft with output:standalone should not trace too many files in next-server.js.nft.json 1`

- Snapshot  - 0
+ Received  + 2

@@ -1,10 +1,11 @@
  [
    "/node_modules/@img/colour/*",
    "/node_modules/@img/sharp-*/sharp-*.node",
    "/node_modules/@img/*",
    "/node_modules/@next/env/*",
+   "/node_modules/@next/routing/*",
    "/node_modules/@swc/helpers/*",
    "/node_modules/client-only/*",
    "/node_modules/detect-libc/*",
    "/node_modules/next/dist/build/adapter/setup-node-env.external.js",
    "/node_modules/next/dist/build/define-env.js",
@@ -43,10 +44,11 @@
    "/node_modules/next/dist/compiled/@edge-runtime/primitives/url.js.text.js",
    "/node_modules/next/dist/compiled/@hapi/accept/index.js",
    "/node_modules/next/dist/compiled/@mswjs/interceptors/ClientRequest/index.js",
    "/node_modules/next/dist/compiled/@napi-rs/triples/index.js",
    "/node_modules/next/dist/compiled/@opentelemetry/api/index.js",
+   "/node_modules/next/dist/compiled/@vercel/routing-utils/superstatic.js",
    "/node_modules/next/dist/compiled/async-retry/index.js",
    "/node_modules/next/dist/compiled/async-sema/index.js",
    "/node_modules/next/dist/compiled/busboy/index.js",
    "/node_modules/next/dist/compiled/bytes/index.js",
    "/node_modules/next/dist/compiled/ci-info/index.js",

  132 |         ]
  133 |
> 134 |         expect(traceGrouped).toMatchInlineSnapshot(`
      |                              ^
  135 |          [
  136 |            "/node_modules/@img/colour/*",
  137 |            "/node_modules/@img/sharp-*/sharp-*.node",

  at Object.toMatchInlineSnapshot (production/next-server-nft/next-server-nft.test.ts:134:30)

Other failing CI jobs

@timneutkens timneutkens force-pushed the codex/server-routing/opt-in-delegation branch from 6b71457 to 19ecc5b Compare May 25, 2026 16:33
Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

Inline snapshot for next-server.js.nft.json is missing two new trace entries (@next/routing and @vercel/routing-utils/superstatic.js) added by the @next/routing dependency.

Fix on Vercel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant