Researched 2026-08-28 against the current Cloudflare, Next.js, OpenNext, and vinext documentation.
Recommendation
Choose the deployment from the application's runtime needs:
| Application shape | Recommended path | Reason | Important caveat |
|---|---|---|---|
| Static HTML, CSS, and JavaScript only | Cloudflare Pages static export | The official Pages guide directly supports Next.js static exports, Git deploys, and pull-request previews | No runtime SSR, ISR, Server Actions, cookies, or other server features |
| New full-stack Next.js application on Cloudflare | Cloudflare Workers with vinext | Cloudflare currently recommends vinext as its default Workers path | vinext is beta; run its compatibility check before adopting it |
| Existing dynamic Next.js application that cannot yet use vinext | Cloudflare Workers with @opennextjs/cloudflare | OpenNext supports the common Next.js server features and is the documented compatibility path | It needs manual Workers configuration; Node.js middleware is not supported |
Cloudflare's current Next.js guide explicitly recommends vinext for Workers, while its OpenNext guide says to use OpenNext for an existing application that has a compatibility gap and migrate when possible. Cloudflare's separate Pages guide is specifically for static exports. Sources: Cloudflare Next.js Workers guide, Cloudflare OpenNext adapter guide, and Cloudflare Pages static Next.js guide.
Best fit for this repository
Use Cloudflare Pages' static export. This app already has the required shape:
next.config.mjssetsoutput: "export"andimages.unoptimized: true.app/[...slug]/page.tsxenumerates the Markdown routes withgenerateStaticParams().lib/content.tsreads the repository's Markdown at build time.package.jsonrunsnext build, then copies Next'soutdirectory todist.
Next.js documents that output: "export" emits an out directory of static assets and disables features that require a server runtime. output: "standalone" is a different mode intended for a self-contained Node.js server, commonly in a Docker container; it is not needed here. Sources: Next.js static exports and Next.js output configuration.
Pages settings
For a Cloudflare Pages project rooted at apps/docs, use:
Root directory: apps/docsBuild command: pnpm buildBuild output directory: distdist matches this repository's existing package script. If the deployment uses pnpm exec next build instead, publish out, which is the directory documented by Cloudflare's static-export preset. Keep the build rooted at apps/docs: the content loader resolves the repository Markdown directory relative to that working directory.
Pages' Git integration rebuilds commits, creates a *.pages.dev deployment, and provides pull-request preview deployments. That is enough for this app; no Workers adapter, Wrangler configuration, R2 cache, or Cloudflare Images binding is required. See the Pages static Next.js guide.
Freshness consequence
The layout calls getRepoActivity(), which fetches GitHub activity during the build. Because this app is a static export, the revalidate: 3600 hint does not create a server that refreshes the data after deployment; the activity is effectively refreshed by the next build. This is an inference from the source and Next.js's static-export behavior. If live activity becomes a requirement, that is a runtime feature and should be separated from this static deployment decision.
Full-stack Workers path: vinext
Use vinext when the application needs server-side rendering, streaming, ISR, Server Actions, middleware, or direct Cloudflare bindings in server code. Cloudflare lists these common features as supported, but marks vinext beta and says to run the compatibility check for an existing production application. Its next/* support is described as mostly supported and image optimization as partial.
For a new project, Cloudflare's current scaffold is:
npm create cloudflare@latest -- my-next-app --framework=nextFor an existing project, the documented safe sequence is:
npx vinext checknpx vinext initnpx @vinext/cloudflare deployvinext init is described as non-destructive: it adds the Vite/Workers setup alongside the existing Next.js setup so the migration can be tested. Review the Cloudflare Next.js guide and the vinext compatibility dashboard before switching production traffic.
This repository currently pins Next.js 15.1.7, so do not run the migration blindly. The Cloudflare guide's existing-project flow names Next.js 16, and the compatibility dashboard is versioned by test run. Upgrade and test in a separate change only if this app actually needs server behavior.
Compatibility fallback: OpenNext
Use OpenNext when an existing dynamic app cannot yet migrate to vinext. Cloudflare's documented configuration is a Workers bundle generated from the normal Next.js build:
pnpm add @opennextjs/cloudflarepnpm add -D wranglernpx @opennextjs/cloudflare migratepnpm run previewpnpm run deployThe resulting Wrangler configuration uses the following important values:
{ "main": ".open-next/worker.js", "compatibility_flags": ["nodejs_compat"], "assets": { "directory": ".open-next/assets", "binding": "ASSETS" }}OpenNext's current Cloudflare guide lists App Router, Pages Router, Route Handlers, React Server Components, SSR, ISR, Server Actions, streaming, and middleware as supported. It does not yet support Node.js in middleware. The guide also requires the nodejs_compat flag and a compatibility date of 2024-09-23 or later; configure an appropriate current date for a new deployment. Sources: Cloudflare OpenNext adapter guide and OpenNext Cloudflare getting started.
Do not combine this path with output: "export": the point of OpenNext is to preserve a server runtime. Do not select the old @cloudflare/next-on-pages path for a new deployment; OpenNext's migration guide identifies it as an Edge-only predecessor and tells existing users to remove it when moving to OpenNext.
Deployment gate for this checkout
The current static build is not green yet. Running pnpm build from apps/docs compiled successfully, then failed during Next.js type checking at app/draw/page.tsx:59 because the installed drawing component does not accept the edge prop. This is an existing application/type dependency issue, not a Cloudflare deployment issue. Resolve it, rerun pnpm build, and verify the generated dist/index.html before creating the Pages project.
Sources
- Cloudflare Next.js on Workers - current default vinext path, feature support, commands, and alternative paths.
- Cloudflare OpenNext adapter - fallback status, feature table, and manual Workers configuration.
- Cloudflare Pages static Next.js - static-export preset,
outoutput, Git deployment, and previews. - Next.js static exports -
output: "export", generated output, and static-runtime limitations. - Next.js output configuration - distinction between default, standalone, and export output modes.
- OpenNext for Cloudflare - runtime/version context and adapter behavior.
- vinext compatibility - current compatibility results and test methodology.