Commit Graph

1 Commits

Author SHA1 Message Date
James Anderson 576c55d7db feat(pages-router): implement _next/data JSON endpoint (#1384)
* feat(pages-router): implement _next/data JSON endpoint

Recognize `/_next/data/<buildId>/<page>.json` in dev and prod request
pipelines. The URL is normalized to the page path BEFORE middleware
runs (matching Next.js' `handleNextDataRequest`), and the server emits
`{ pageProps }` as JSON with `Content-Type: application/json` instead
of the rendered HTML.

Closes #1330

* fix(pages-router): address bigbonk findings on _next/data endpoint

- Delegate JSON envelope construction from the generated entry to the
  typed `buildNextDataJsonResponse` helper so the envelope shape lives
  in one place (entries stay thin per AGENTS.md).
- Return a JSON 404 from `resolvePagesPageData` when `getStaticPaths`
  with `fallback: false` rejects the path for a data request. Without
  this, client-side navigations to unlisted slugs got an HTML 404 body
  which fails to parse as JSON in the Next.js client router.
- Apply the same JSON-404 gating in the dev server for
  `getStaticPaths fallback:false`, `getServerSideProps.notFound`, and
  `getStaticProps.notFound` paths.
- Read the dev buildId from the plugin's resolved `nextConfig.buildId`
  first so a user-supplied `generateBuildId` is honored, matching the
  value embedded into the prod server entry.
- Add coverage for `getStaticProps` data requests and the
  `fallback:false` JSON-404 path.

* chore: drop unused NextDataMatch export (knip)

* fix(pages-router): JSON 404 for dev stale buildId; HTML 404 for gSSP/gSP notFound on HTML nav

Follow-ups from bigbonk round 2:

- Dev request pipeline now returns a JSON 404 when `_next/data/<wrong>` is
  hit, mirroring the prod-server path. Previously the dev fall-through
  served Vite's HTML 404, breaking client routers that try to parse the
  body as JSON.
- `resolvePagesPageData` now gates the gSSP/gSP `notFound: true` 404 body
  on `isDataReq` so HTML navigations get the HTML 404 page and data
  requests get the JSON envelope. Previously both shapes always returned
  the JSON body, which surfaced text-content-type mismatches on HTML
  navigations through gSSP/gSP `notFound`.
2026-05-21 15:55:33 +01:00