Skip to content

Revert "Revert "refactor: write pages router export files directly to server/pages/""#93409

Merged
timneutkens merged 5 commits into
canaryfrom
revert-92733-revert-90018-fix/export-write-directly-to-server-pages-new
May 26, 2026
Merged

Revert "Revert "refactor: write pages router export files directly to server/pages/""#93409
timneutkens merged 5 commits into
canaryfrom
revert-92733-revert-90018-fix/export-write-directly-to-server-pages-new

Conversation

@timneutkens
Copy link
Copy Markdown
Contributor

@timneutkens timneutkens commented May 1, 2026

Re-apply #92735

Before re-landing we need to investigate why the pages router middleware i18n test fails when deployed.

Update: Investigation/fix: #92735 (comment)

Reverts #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 at line 2988:

                  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: 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 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).

@github-actions github-actions Bot added create-next-app Related to our CLI tool for quickly starting a new Next.js application. created-by: Turbopack team PRs by the Turbopack team. Documentation Related to Next.js' official documentation. tests Turbopack Related to Turbopack with Next.js. type: next labels May 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

Tests Passed

Commit: aab320f

@timneutkens timneutkens force-pushed the revert-92733-revert-90018-fix/export-write-directly-to-server-pages-new branch from 01e968d to aab320f Compare May 22, 2026 15:49
@timneutkens timneutkens merged commit c7a5a09 into canary May 26, 2026
298 of 301 checks passed
@timneutkens timneutkens deleted the revert-92733-revert-90018-fix/export-write-directly-to-server-pages-new branch May 26, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

create-next-app Related to our CLI tool for quickly starting a new Next.js application. created-by: Turbopack team PRs by the Turbopack team. Documentation Related to Next.js' official documentation. tests Turbopack Related to Turbopack with Next.js. type: next

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants