Files
James Anderson 2d035d47bd fix: await top-level await module imports (#1381)
* fix: make next/document default export a class

Next.js's `next/document` default export is `class Document extends
React.Component`. vinext's shim exported a function, so user
`_document.tsx` files that use the class-based form (the common Next.js
idiom: `class MyDocument extends Document`) ended up extending a
function. React refuses to call class constructors without `new`, which
caused SSR to throw "Class constructor MyDocument cannot be invoked
without 'new'" — surfacing in e2e as 500 / empty responses.

This is the actual root cause of the "async modules render empty pages"
report (issue #1361): the Next.js `test/e2e/async-modules` fixture's
`pages/_document.jsx` uses `class extends Document`, and once it crashes
the whole page renders empty. Top-level await itself propagates
correctly through Rolldown's static-import graph already.

Adds a class-based Document shim that mirrors Next.js's signature
(static `getInitialProps`, instance `render()`), plus production-build
e2e coverage for pages, `_app.tsx`, `getStaticProps`,
`getServerSideProps`, API routes, and class-based `_document.tsx`, all
using top-level `await`.

Closes #1361

Ports from Next.js: test/e2e/async-modules/index.test.ts
https://github.com/vercel/next.js/blob/canary/test/e2e/async-modules/index.test.ts

* fix(next/document): align Document base class with Next.js's typed contract

Addresses Bonk review feedback on PR #1381:

- Export DocumentContext / DocumentInitialProps types matching Next.js,
  so subclasses that delegate via `await Document.getInitialProps(ctx)`
  receive typed objects. The runtime path is still a stub (the Pages
  Router renderPage/defaultGetInitialProps chain is not wired up), but
  the signatures pin the contract.
- Declare the default Document class export in next-shims.d.ts so
  strict-mode consumers don't see `any` for `import Document from
  "next/document"`.
- Add a class-extends regression test in tests/document.test.ts — this
  is the contract that broke in issue #1361 (the original Next.js
  `pages/_document.jsx` uses `class extends Document`).
- Switch the class generic default from `unknown` to `{}` to match
  Next.js's `class Document<P = {}>`.
- Clarify App Router fixture comment: the upstream Next.js async-modules
  suite is Pages-Router-only, so this is adapted, not ported verbatim.
2026-05-21 12:03:33 +01:00
..