Commit Graph

3 Commits

Author SHA1 Message Date
James Anderson 31e87439df fix(pages-router): retain prefetched SSG data (#2366)
* fix(pages-router): retain prefetched SSG data

* fix(pages-router): align SSG export detection

* fix(pages-router): skip data prefetch for non-SSG routes

* fix(pages-router): align data navigation with Next.js

* chore: avoid exporting middleware matcher helper type

* fix(pages-router): preserve client navigation effects

* fix(pages-router): preserve query rewrite history timing

* fix(pages-router): keep data fetch startup synchronous

* fix(pages-router): keep superseded data fetches alive

* fix(pages-router): skip nonmatching redirect matcher awaits

* fix(pages-router): reuse middleware SSR prefetch data

* Fix pages data prefetch CI regressions

* fix(pages-router): evict middleware prefetch cache
2026-06-29 14:52:35 +01:00
James Anderson 48f4df28cb fix(pages-router): cancel deduped GSSP data waits (#2038) 2026-06-15 22:58:02 +01:00
James Anderson 26d1cc79bc fix(pages-router): dedupe in-flight _next/data fetches by URL (#1464) (#1684)
Concurrent `Router.push` calls (or back-to-back `<Link>` clicks) to the
same gSSP route each fired their own `_next/data/<id>/<page>.json` fetch.
The Next.js parity test asserts `hit: 1` after 4 rapid navigations to a
slow page; vinext was producing `hit: N`.

Add a module-scoped in-flight Promise cache keyed by the resolved data
URL, mirroring `fetchNextData()`'s `inflightCache` in
`packages/next/src/shared/lib/router/router.ts`. Concurrent callers share
one `fetch()` invocation and each receive a cloned Response. Entries
self-evict on settle so the next navigation re-fetches fresh.

The shared fetch deliberately ignores per-caller `AbortSignal`s: stale
navigations are already detected via `_navigationId` + `assertStillCurrent()`
checkpoints after the await, and aborting the shared request on behalf of
one superseded caller would destroy the dedup gain for every other
concurrent caller. Pre-await abort still surfaces so callers see the
documented `NavigationCancelledError` / `AbortError` when supersession
happened before the fetch was even attempted.

Wired into both `navigateClientData()` (the JSON fast path) and
`resolveMiddlewareDataRedirect()` (the soft-redirect probe).
2026-06-01 11:14:00 +01:00