2026-09-13 · T2 Team · 5 次阅读

How to Deploy Next.js to Cloudflare Pages in 2026 (Step by Step)

We migrated our Next.js 14 app from Vercel to Cloudflare Pages. Here's the exact playbook, with cost and latency data.

How to Deploy Next.js to Cloudflare Pages in 2026

We migrated our Next.js 14 app (47 pages, ISR enabled, 2 edge functions) from Vercel to Cloudflare Pages. Here's the exact playbook — including cost, latency, and gotchas.

Why We Moved

Our Vercel bill hit $87/month for what we considered a small app:

  • $42 from Image Optimization
  • $31 from Edge Function invocations
  • $14 from ISR cache misses
  • We tested Cloudflare Pages. After 30 days of production traffic, here's what we found.

    The Migration (8 Steps)

    1. Prerequisites

  • A Cloudflare account (free)
  • Next.js 14+ project
  • A custom domain on Cloudflare DNS
  • 2. Install the Worker Adapter

    Cloudflare's Next.js support is via the OpenNext Cloudflare adapter:

    ``bash npm install @opennextjs/cloudflare `

    Add to next.config.js:

    `js import { initOpenNextCloudflareForDev } from '@opennextjs/cloudflare'; initOpenNextCloudflareForDev(); export default { /* your existing config */ }; `

    3. Add the Build Script

    `json { "scripts": { "preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview", "deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy", "cf-typegen": "wrangler types --env-file=.env.production" } } `

    4. Configure wrangler.toml

    `toml name = "my-next-app" compatibility_date = "2025-01-01" compatibility_flags = ["nodejs_compat"] pages_build_output_dir = ".open-next/dist"

    [vars] NEXTJS_ENV = "production" `

    5. Set Up Git Integration

    In Cloudflare Dashboard:

  • Workers & Pages → Create application → Pages → Connect to Git
  • Select your repo
  • Build command: npm run build
  • Build output: .open-next/dist
  • Root directory: /
  • 6. Add Environment Variables

    In Pages → Settings → Environment variables:

  • NEXT_PUBLIC_API_URL
  • DATABASE_URL (use Cloudflare Hyperdrive!)
  • Any secrets
  • 7. Configure Custom Domain

    Pages → Custom domains → Set up a custom domain.

    8. Enable Hyperdrive (for databases)

    If you use Postgres/Neon, enable Hyperdrive for 10x latency reduction:

    `toml [[hyperdrive_bindings]] binding = "HYPERDRIVE" id = "your-hyperdrive-id" `

    Real-World Results (After 30 Days)

    | Metric | Vercel | Cloudflare Pages | |--------|--------|-------------------| | Monthly cost | $87 | $0 (free tier) | | P50 latency (US) | 142ms | 78ms | | P50 latency (EU) | 189ms | 41ms | | P50 latency (Asia) | 387ms | 62ms | | Deploy time | 1m 12s | 1m 28s | | ISR support | ✅ | ✅ | | Edge runtime | ✅ | ✅ | | Image optimization | ✅ ($42/mo!) | ✅ (free) | | Bandwidth | $0.15/GB | Free |

    The Gotchas

  • No build-time environment variables in edge runtime — use getCloudflareContext() instead
  • ISR cache purge has 30s delay — not instant like Vercel
  • No output: 'standalone'` support — must use OpenNext adapter
  • Cloudflare Workers limit: 10MB bundle size (Vercel is 250MB)
  • Database connections: use Hyperdrive, never connect directly to Postgres
  • When NOT to Switch

  • Your app is serverful (long-running WebSockets, etc.)
  • You need bytecode-level custom Vercel integrations
  • You use Vercel-specific features (Edge Middleware, Image Optimization specific tweaks)
  • When You Should Switch

  • Cost-sensitive (saving >$50/month)
  • Global audience (Cloudflare's edge network is unbeatable)
  • Static-first apps
  • You're hitting Vercel bandwidth limits

TL;DR

We saved $87/month and got 2-6x faster latency globally. The migration took 4 hours. Worth it for our use case.


*Published 2026-09-13 by T2 Team · 8 min read*

📚 相关阅读

← 返回文章列表