next.js
c7a5a095 - Revert "Revert "refactor: write pages router export files directly to server/pages/"" (#93409)

Commit
125 days ago
Revert "Revert "refactor: write pages router export files directly to server/pages/"" (#93409) Re-apply #92735 Before re-landing we need to investigate why the pages router middleware i18n test fails when deployed. Update: Investigation/fix: https://github.com/vercel/next.js/pull/92735#issuecomment-4242978559 Reverts vercel/next.js#92733 --- Cursor plan based on the investigation Claude did: # Fix i18n export orphan HTML files in server/pages/ ## Problem When i18n is configured, the export path map in `build/index.ts` creates locale-prefixed entries for every page (e.g., `/en/home/a`, `/fr/home/a`), but only deletes the non-locale entry from `defaultMap` for SSG pages. For non-SSG static pages, the non-locale entry (e.g., `/home/a`) remains, causing the export worker to render and write orphan HTML files directly to `server/pages/`. These orphan files interfere with routing on deployment platforms (e.g., a `[teamId]/[slug].html` orphan matches rewritten paths that should 404). ## Root Cause In [packages/next/src/build/index.ts](packages/next/src/build/index.ts) at line 2988: ```2988:2991:packages/next/src/build/index.ts if (isSsg) { // remove non-locale prefixed variant from defaultMap delete defaultMap[page] } ``` The `if (isSsg)` guard means non-SSG pages keep their non-locale entry, which gets rendered and written to `server/pages/` as an orphan file. ## Fix **Single-line change** in [packages/next/src/build/index.ts](packages/next/src/build/index.ts): Remove the `if (isSsg)` guard so `delete defaultMap[page]` always runs when i18n is enabled. The locale-prefixed entries are already created in the loop above (line 2981), and they capture the original `page` value via `defaultMap[page]?.page || page`. The non-locale entry is not needed after that -- in the old staging-directory flow (`moveExportedPage`), it was rendered but never moved to the final output directory. **Safety verification:** - `updatePagesManifestForExportedPage` (line 3754) is called based on `combinedPages`, not the export map -- it still correctly replaces non-locale manifest entries with locale-prefixed ones - `pageDuration` tracking (line 3745) may return `undefined` for the non-locale path, but this is typed `number | undefined` and used with `|| 0` fallback at line 375 of `build/utils.ts` -- purely cosmetic - SSG pages already have this exact behavior (delete from defaultMap), so this change makes non-SSG consistent with SSG - The `ssgPageDurations` invariant check (line 3737-3738) only runs for SSG pages, which are unaffected ## Test Add assertions to the existing i18n integration test at [test/integration/i18n-support/test/index.test.ts](test/integration/i18n-support/test/index.test.ts) to verify that non-locale-prefixed HTML orphans do not exist in `server/pages/` after build. The test already has production mode assertions checking locale-prefixed file existence and manifest correctness (lines 81-99).
Author
Parents
Loading