[GH-ISSUE #9] Static pre-rendering at build time #1

Open
opened 2026-05-06 12:36:20 +02:00 by BreizhHardware · 8 comments

Originally created by @southpolesteve on GitHub (Feb 24, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/9

Summary

Next.js pre-renders static pages to HTML at build time. Pages without dynamic data fetching get rendered once during next build, and the resulting HTML is served directly without any server-side work at request time.

vinext currently does not do this. All pages are server-rendered on the first request, then cached via ISR. This works well for most apps, but purely static sites don't get the benefit of zero-compute serving from the start.

Why it matters

  • Performance: Pre-rendered HTML can be served from a CDN edge with zero compute cost at request time.
  • Feature parity: generateStaticParams() is a commonly used Next.js API. Supporting it expands the set of apps that can migrate to vinext without changes.
  • Build comparison: Part of Next.js's build time is spent pre-rendering. Adding pre-rendering to vinext would make build time comparisons more complete.

Current workaround

vinext supports ISR out of the box. After the first request to any page, it's cached and revalidated in the background. For most production apps with any amount of traffic, the practical difference is minimal: one cold render per page after deploy.

For sites that are 100% static content with no dynamic routes, a static-first framework like Astro may be a better fit today.

What pre-rendering would look like

  • During vinext build, identify pages that are fully static (no cookies(), headers(), dynamic data fetching, etc.)
  • Render those pages to HTML and write to the output directory
  • For pages with generateStaticParams(), enumerate the params and pre-render each variant
  • The production server serves pre-rendered HTML when available, falling back to SSR for dynamic pages

Traffic-aware Pre-Rendering (TPR)

We're also experimenting with an alternative approach: instead of pre-rendering every page at build time, query Cloudflare's zone analytics to identify which pages actually receive traffic and only pre-render those. See the blog post for details.

This is available today behind vinext deploy --experimental-tpr.

Status

This is on the roadmap. Contributions welcome.

Originally created by @southpolesteve on GitHub (Feb 24, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/9 ## Summary Next.js pre-renders static pages to HTML at build time. Pages without dynamic data fetching get rendered once during `next build`, and the resulting HTML is served directly without any server-side work at request time. vinext currently does not do this. All pages are server-rendered on the first request, then cached via ISR. This works well for most apps, but purely static sites don't get the benefit of zero-compute serving from the start. ## Why it matters - **Performance**: Pre-rendered HTML can be served from a CDN edge with zero compute cost at request time. - **Feature parity**: `generateStaticParams()` is a commonly used Next.js API. Supporting it expands the set of apps that can migrate to vinext without changes. - **Build comparison**: Part of Next.js's build time is spent pre-rendering. Adding pre-rendering to vinext would make build time comparisons more complete. ## Current workaround vinext supports ISR out of the box. After the first request to any page, it's cached and revalidated in the background. For most production apps with any amount of traffic, the practical difference is minimal: one cold render per page after deploy. For sites that are 100% static content with no dynamic routes, a static-first framework like [Astro](https://astro.build/) may be a better fit today. ## What pre-rendering would look like - During `vinext build`, identify pages that are fully static (no `cookies()`, `headers()`, dynamic data fetching, etc.) - Render those pages to HTML and write to the output directory - For pages with `generateStaticParams()`, enumerate the params and pre-render each variant - The production server serves pre-rendered HTML when available, falling back to SSR for dynamic pages ## Traffic-aware Pre-Rendering (TPR) We're also experimenting with an alternative approach: instead of pre-rendering every page at build time, query Cloudflare's zone analytics to identify which pages actually receive traffic and only pre-render those. See the blog post for details. This is available today behind `vinext deploy --experimental-tpr`. ## Status This is on the roadmap. Contributions welcome.
Author
Owner

@noxify commented on GitHub (Feb 24, 2026):

did the rsc ssg part with generateStaticParams support some months ago as experiment.

Maybe it helps the AI to get some inspiration ;)

<!-- gh-comment-id:3954639292 --> @noxify commented on GitHub (Feb 24, 2026): did the rsc ssg part with `generateStaticParams` support some months ago as experiment. Maybe it helps the AI to get some inspiration ;) * plugin: https://github.com/noxify/vite-renoun-docs/blob/main/src/framework/plugin.ts * page example: https://github.com/noxify/vite-renoun-docs/blob/main/src/pages/docs/%5Bcollection%5D/%5B...slug%5D/page.tsx
Author
Owner

@riderx commented on GitHub (Feb 24, 2026):

There is a big use case of pre render build time you missing in Nextjs.
Mobile apps!
My biggest SEO article is https://capgo.app/blog/building-a-native-mobile-app-with-nextjs-and-capacitor/
It drives me the most traffic, basically they publish they endpoint as API and use the buildJS in web and mobile.
This make one codebase run it all and it's quite convenient!
I'm waiting for this feature to be release and then I do the same article for vinext

<!-- gh-comment-id:3955069566 --> @riderx commented on GitHub (Feb 24, 2026): There is a big use case of pre render build time you missing in Nextjs. **Mobile apps!** My biggest SEO article is https://capgo.app/blog/building-a-native-mobile-app-with-nextjs-and-capacitor/ It drives me the most traffic, basically they publish they endpoint as API and use the buildJS in web and mobile. This make one codebase run it all and it's quite convenient! I'm waiting for this feature to be release and then I do the same article for vinext
Author
Owner

@stavros-k commented on GitHub (Feb 26, 2026):

Please when implementing this, consider not erroring out whe generateStaticParams return an empty array. Just don't render anything on that route!

https://github.com/vercel/next.js/issues/61213

<!-- gh-comment-id:3965055313 --> @stavros-k commented on GitHub (Feb 26, 2026): Please when implementing this, consider _not_ erroring out whe `generateStaticParams` return an empty array. Just don't render anything on that route! https://github.com/vercel/next.js/issues/61213
Author
Owner

@Meldiron commented on GitHub (Feb 27, 2026):

When implementing this, please consider scenario of static build while paths have dynamic sections /articles/[slug], andpage.tsx does not have generateStaticParams.

This is common SPA scenario with client-side data fetching which Next.js currently does not support and community has been asking and following this topic for years. There was even moment when Next.js promised it in minor version, and 2 major versions later, we still dont have it.

One huge (out of many) related discussions: https://github.com/vercel/next.js/discussions/55393

<!-- gh-comment-id:3971383404 --> @Meldiron commented on GitHub (Feb 27, 2026): When implementing this, please consider scenario of static build while paths have dynamic sections `/articles/[slug]`, and`page.tsx` does not have `generateStaticParams`. This is common SPA scenario with client-side data fetching which Next.js currently **does not support** and community has been asking and following this topic for years. There was even moment when Next.js promised it in minor version, and 2 major versions later, we still dont have it. One huge (out of many) related discussions: https://github.com/vercel/next.js/discussions/55393
Author
Owner

@jon-hotaisle commented on GitHub (Mar 8, 2026):

I don't know if this is helpful or not, but I managed to convince AI to render our website as static. I don't even know if it is correct, I didn't bother to read the code, but the output seems fine...

https://github.com/hotaisle/hotaisle-website/blob/main/scripts/build_static.ts

<!-- gh-comment-id:4020217497 --> @jon-hotaisle commented on GitHub (Mar 8, 2026): I don't know if this is helpful or not, but I managed to convince AI to render our website as static. I don't even know if it is correct, I didn't bother to read the code, but the output seems fine... https://github.com/hotaisle/hotaisle-website/blob/main/scripts/build_static.ts
Author
Owner

@james-elicx commented on GitHub (Mar 16, 2026):

Opt-in pre-rendering functionality has been merged in for build-time and deploy-time, however, that does not represent a complete feature as there are several other things required for it to be fully usable by deployed applications, and it should be considered somewhat experimental at the moment. Therefore, I'm leaving this issue open with several sub-issues attached.

<!-- gh-comment-id:4070092680 --> @james-elicx commented on GitHub (Mar 16, 2026): Opt-in pre-rendering functionality has been merged in for build-time and deploy-time, however, that does not represent a complete feature as there are several other things required for it to be fully usable by deployed applications, and it should be considered somewhat experimental at the moment. Therefore, I'm leaving this issue open with several sub-issues attached.
Author
Owner

@JamesbbBriz commented on GitHub (Mar 28, 2026):

I'd like to pick up #563 (configurable concurrency + RSC dedup) and #564 (E2E test fixture for static exports) — planning to bundle them into a single PR.

I've been running vinext on Cloudflare Workers in production (Prisma + Hyperdrive) and have hands-on experience with the pre-render pipeline. Will start with the E2E fixture and layer in the concurrency flag on top.

Let me know if there's anything to be aware of before I start!

<!-- gh-comment-id:4147279116 --> @JamesbbBriz commented on GitHub (Mar 28, 2026): I'd like to pick up #563 (configurable concurrency + RSC dedup) and #564 (E2E test fixture for static exports) — planning to bundle them into a single PR. I've been running vinext on Cloudflare Workers in production (Prisma + Hyperdrive) and have hands-on experience with the pre-render pipeline. Will start with the E2E fixture and layer in the concurrency flag on top. Let me know if there's anything to be aware of before I start!
Author
Owner

@james-elicx commented on GitHub (Mar 28, 2026):

I'd like to pick up #563 (configurable concurrency + RSC dedup) and #564 (E2E test fixture for static exports) — planning to bundle them into a single PR.

I've been running vinext on Cloudflare Workers in production (Prisma + Hyperdrive) and have hands-on experience with the pre-render pipeline. Will start with the E2E fixture and layer in the concurrency flag on top.

Let me know if there's anything to be aware of before I start!

Hi @JamesbbBriz, thanks for the interest! E2Es for the static export fixture were just merged in as another contributor submitted a PR to add some, but more are always welcome!

Feel free to raise PRs as you go :)

<!-- gh-comment-id:4147727791 --> @james-elicx commented on GitHub (Mar 28, 2026): > I'd like to pick up [#563](https://github.com/cloudflare/vinext/issues/563) (configurable concurrency + RSC dedup) and [#564](https://github.com/cloudflare/vinext/issues/564) (E2E test fixture for static exports) — planning to bundle them into a single PR. > > I've been running vinext on Cloudflare Workers in production (Prisma + Hyperdrive) and have hands-on experience with the pre-render pipeline. Will start with the E2E fixture and layer in the concurrency flag on top. > > Let me know if there's anything to be aware of before I start! Hi @JamesbbBriz, thanks for the interest! E2Es for the static export fixture were just merged in as another contributor submitted a PR to add some, but more are always welcome! Feel free to raise PRs as you go :)
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#1
No description provided.