[PR #274] [CLOSED] feat: static pre-rendering at build time #433

Closed
opened 2026-05-06 12:39:47 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/274
Author: @NathanDrake2406
Created: 3/5/2026
Status: Closed

Base: mainHead: feat/static-prerender-build


📝 Commits (10+)

  • 5e56610 feat: wire output: 'export' to vinext build
  • 2149bed feat: add prerenderStaticPages() for build-time pre-rendering
  • bbcf6e4 feat: serve pre-rendered HTML from prod server
  • f44f446 feat: wire prerenderStaticPages() into vinext build
  • 1b8a0f9 fix: address 6 bugs found in code review
  • df3830f fix: downgrade missing generateStaticParams/getStaticPaths from error to warning
  • ce830ad fix: address code review findings in static export
  • 5be5d1c refactor: improve observability and type safety in static export
  • 69a5835 fix: address 5 issues from code review audit
  • 0ad2979 merge: resolve conflict with upstream/main

📊 Changes

20 files changed (+1723 additions, -166 deletions)

View changed files

📝 packages/vinext/src/build/report.ts (+76 -9)
📝 packages/vinext/src/build/static-export.ts (+808 -133)
📝 packages/vinext/src/cli.ts (+91 -1)
📝 packages/vinext/src/entries/pages-server-entry.ts (+5 -8)
📝 packages/vinext/src/server/prod-server.ts (+111 -0)
📝 pnpm-lock.yaml (+21 -0)
📝 tests/__snapshots__/entry-templates.test.ts.snap (+2 -8)
📝 tests/app-router.test.ts (+4 -6)
tests/build-prerender.test.ts (+272 -0)
tests/build-static-export.test.ts (+222 -0)
tests/fixtures/app-basic/app/empty-gsp/[slug]/page.tsx (+9 -0)
tests/fixtures/hybrid-basic/app/about/page.tsx (+8 -0)
tests/fixtures/hybrid-basic/app/layout.tsx (+13 -0)
tests/fixtures/hybrid-basic/app/page.tsx (+8 -0)
tests/fixtures/hybrid-basic/package.json (+13 -0)
tests/fixtures/hybrid-basic/pages/legacy.tsx (+8 -0)
tests/fixtures/hybrid-basic/tsconfig.json (+12 -0)
tests/fixtures/hybrid-basic/vite.config.ts (+6 -0)
📝 tests/pages-router.test.ts (+34 -0)
📝 tests/static-export.test.ts (+0 -1)

📄 Description

Summary

Implements build-time static pre-rendering for vinext, closing #9.

  • vinext build with output: "export" now runs full static export to out/ (Phase 1)
  • vinext build in normal mode pre-renders static pages to dist/server/pages/ (Phase 2)
  • Production server serves pre-rendered HTML before falling through to SSR
  • vinext start rejects export builds with a helpful error message

Phase 1: output: "export" support

Adds runStaticExport() orchestrator that connects the existing staticExportPages/staticExportApp functions to the CLI build pipeline. Loads config, detects router type, starts a temp dev server, scans routes, renders all static pages to out/.

Phase 2: Selective pre-rendering in normal builds

Adds prerenderStaticPages() that runs after production builds:

  1. Starts a temp prod server in-process
  2. Detects static routes via Vite dev server module inspection (skips getServerSideProps, force-dynamic, etc.)
  3. Fetches each static route and writes HTML to dist/server/pages/
  4. Prod server checks for pre-rendered HTML before SSR fallback

Files changed

File Change
packages/vinext/src/build/static-export.ts runStaticExport(), prerenderStaticPages(), collectStaticRoutes()
packages/vinext/src/cli.ts Wire both phases into buildApp(), export build rejection in start()
packages/vinext/src/server/prod-server.ts resolvePrerenderedHtml() + pre-render serving in both router handlers
tests/build-static-export.test.ts 14 tests for runStaticExport() (both routers)
tests/build-prerender.test.ts 7 tests for prod server serving + prerenderStaticPages()

Test plan

  • pnpm run typecheck passes
  • pnpm run lint passes
  • 21 new tests pass (14 static export + 7 prerender)
  • Full test suite: 2183 passed, 6 pre-existing App Router static export HTTP serving failures unchanged (fixed by #273)
  • CI checks (Lint, Typecheck, Vitest, Playwright E2E)

Closes #9


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/274 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 3/5/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `feat/static-prerender-build` --- ### 📝 Commits (10+) - [`5e56610`](https://github.com/cloudflare/vinext/commit/5e56610fa8f4216fa3de913790e3efd50cf3a8aa) feat: wire output: 'export' to vinext build - [`2149bed`](https://github.com/cloudflare/vinext/commit/2149bed7530f4769db2e84680a9e2c6b0debbe23) feat: add prerenderStaticPages() for build-time pre-rendering - [`bbcf6e4`](https://github.com/cloudflare/vinext/commit/bbcf6e4910080265dbf0486482d1d0ac872cbdc1) feat: serve pre-rendered HTML from prod server - [`f44f446`](https://github.com/cloudflare/vinext/commit/f44f44692ac72c6aa42e0aae9bb94101920f626a) feat: wire prerenderStaticPages() into vinext build - [`1b8a0f9`](https://github.com/cloudflare/vinext/commit/1b8a0f9769f0b6bb886c8b8f6c274f766122909f) fix: address 6 bugs found in code review - [`df3830f`](https://github.com/cloudflare/vinext/commit/df3830f05d0a56d43e0b3d0b8d81cfc16297a6fd) fix: downgrade missing generateStaticParams/getStaticPaths from error to warning - [`ce830ad`](https://github.com/cloudflare/vinext/commit/ce830ad415eebc8ad0ed53ba26566a45288bf1ce) fix: address code review findings in static export - [`5be5d1c`](https://github.com/cloudflare/vinext/commit/5be5d1ce11ff513922901b9bcba8380be8422c46) refactor: improve observability and type safety in static export - [`69a5835`](https://github.com/cloudflare/vinext/commit/69a5835e0bd70b5f465b958dd8d4805ed4368cdb) fix: address 5 issues from code review audit - [`0ad2979`](https://github.com/cloudflare/vinext/commit/0ad2979de66057312f6da4c6fa955743ef80c682) merge: resolve conflict with upstream/main ### 📊 Changes **20 files changed** (+1723 additions, -166 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/build/report.ts` (+76 -9) 📝 `packages/vinext/src/build/static-export.ts` (+808 -133) 📝 `packages/vinext/src/cli.ts` (+91 -1) 📝 `packages/vinext/src/entries/pages-server-entry.ts` (+5 -8) 📝 `packages/vinext/src/server/prod-server.ts` (+111 -0) 📝 `pnpm-lock.yaml` (+21 -0) 📝 `tests/__snapshots__/entry-templates.test.ts.snap` (+2 -8) 📝 `tests/app-router.test.ts` (+4 -6) ➕ `tests/build-prerender.test.ts` (+272 -0) ➕ `tests/build-static-export.test.ts` (+222 -0) ➕ `tests/fixtures/app-basic/app/empty-gsp/[slug]/page.tsx` (+9 -0) ➕ `tests/fixtures/hybrid-basic/app/about/page.tsx` (+8 -0) ➕ `tests/fixtures/hybrid-basic/app/layout.tsx` (+13 -0) ➕ `tests/fixtures/hybrid-basic/app/page.tsx` (+8 -0) ➕ `tests/fixtures/hybrid-basic/package.json` (+13 -0) ➕ `tests/fixtures/hybrid-basic/pages/legacy.tsx` (+8 -0) ➕ `tests/fixtures/hybrid-basic/tsconfig.json` (+12 -0) ➕ `tests/fixtures/hybrid-basic/vite.config.ts` (+6 -0) 📝 `tests/pages-router.test.ts` (+34 -0) 📝 `tests/static-export.test.ts` (+0 -1) </details> ### 📄 Description ## Summary Implements build-time static pre-rendering for vinext, closing #9. - `vinext build` with `output: "export"` now runs full static export to `out/` (Phase 1) - `vinext build` in normal mode pre-renders static pages to `dist/server/pages/` (Phase 2) - Production server serves pre-rendered HTML before falling through to SSR - `vinext start` rejects export builds with a helpful error message ### Phase 1: `output: "export"` support Adds `runStaticExport()` orchestrator that connects the existing `staticExportPages`/`staticExportApp` functions to the CLI build pipeline. Loads config, detects router type, starts a temp dev server, scans routes, renders all static pages to `out/`. ### Phase 2: Selective pre-rendering in normal builds Adds `prerenderStaticPages()` that runs after production builds: 1. Starts a temp prod server in-process 2. Detects static routes via Vite dev server module inspection (skips `getServerSideProps`, `force-dynamic`, etc.) 3. Fetches each static route and writes HTML to `dist/server/pages/` 4. Prod server checks for pre-rendered HTML before SSR fallback ### Files changed | File | Change | |------|--------| | `packages/vinext/src/build/static-export.ts` | `runStaticExport()`, `prerenderStaticPages()`, `collectStaticRoutes()` | | `packages/vinext/src/cli.ts` | Wire both phases into `buildApp()`, export build rejection in `start()` | | `packages/vinext/src/server/prod-server.ts` | `resolvePrerenderedHtml()` + pre-render serving in both router handlers | | `tests/build-static-export.test.ts` | 14 tests for `runStaticExport()` (both routers) | | `tests/build-prerender.test.ts` | 7 tests for prod server serving + `prerenderStaticPages()` | ## Test plan - [x] `pnpm run typecheck` passes - [x] `pnpm run lint` passes - [x] 21 new tests pass (14 static export + 7 prerender) - [x] Full test suite: 2183 passed, 6 pre-existing App Router static export HTTP serving failures unchanged (fixed by #273) - [x] CI checks (Lint, Typecheck, Vitest, Playwright E2E) Closes #9 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:39:47 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#433
No description provided.