---
title: "What We Learned Shipping Next.js on Cloudflare Without Splitting the Product Apart"
description: "A unified Next.js codebase can run on Cloudflare Pages without splitting the frontend and backend apart, using the @cloudflare/next-on-pages adapter — but it means rewriting Node.js-dependent code to use Web APIs, replacing ISR with a Cloudflare KV caching layer, and switching to stateless JWT-based authentication."
answer_summary: "A unified Next.js codebase can run on Cloudflare Pages without splitting the frontend and backend apart, using the @cloudflare/next-on-pages adapter — but it means rewriting Node.js-dependent code to use Web APIs, replacing ISR with a Cloudflare KV caching layer, and switching to stateless JWT-based authentication."
canonical: "https://nqz.ai/blog/what-we-learned-shipping-nextjs-on-cloudflare"
published_at: "2026-06-12T12:30:00.000Z"
updated_at: "2026-09-10T12:52:00.038Z"
author: "Palash Bagchi"
category: "Engineering"
tags: ["cloudflare","nextjs","routing","opennext"]
image: "https://nqz.ai/blog/covers/what-we-learned-shipping-nextjs-on-cloudflare.webp"
---

# What We Learned Shipping Next.js on Cloudflare Without Splitting the Product Apart

# What We Learned Shipping Next.js on Cloudflare Without Splitting the Product Apart

The conventional advice for moving a Next.js SaaS application to Cloudflare's edge network is to split the product: serve the static frontend from Cloudflare Pages and run the API separately on Node.js servers. That split isn't always necessary. Teams that want one codebase, one deployment pipeline, and the closest possible developer experience to running Next.js on Vercel can keep the product unified — but it takes deliberate adaptation to the edge runtime.

## Why a Unified Approach Can Make Sense

**Direct answer:** For a typical real-time analytics dashboard — authenticated users, server-rendered aggregated metrics and charts, occasional mutations like saving preferences — maintaining two separate repos (frontend and API) adds real CI/CD overhead and slows feature delivery, especially for a small team.

Cloudflare Pages with the `@cloudflare/next-on-pages` adapter aims to bring full Next.js support to the edge, including server components and middleware. Trying it without splitting the product is a reasonable first step: if it works, you get global latency improvements and one less set of servers to manage; if it doesn't, a split architecture is still available as a fallback.

## The Technical Stack and Initial Challenges

A typical stack for this kind of migration looks like:

- **Next.js** (App Router) with server components and streaming
- **Cloudflare Pages** for hosting
- **`@cloudflare/next-on-pages`** as the build adapter
- **Cloudflare KV** for session cache and cache invalidation
- **Cloudflare D1** (SQLite) for lightweight relational queries
- **Wrangler CLI** for deployments

The most common first failure is Node.js-specific code: middleware using `crypto.randomUUID()` from Node's `crypto` module, or server components importing `fs` or `path`, will break immediately, because Cloudflare's edge runtime doesn't support Node.js built-ins. Getting a Next.js app running on the edge generally means rewriting any code that depends on those modules to use Web APIs or Cloudflare-native services instead.

## Key Adaptations to Expect

### Data Fetching and Caching

Moving from Node.js-based fetch (`node-fetch`, `undici`) to the standard Web Fetch API is usually the easy part — most modern libraries already use `fetch`, and Cloudflare's edge runtime supports it natively. Caching is the harder part.

Next.js Incremental Static Regeneration (ISR) is not fully supported on Cloudflare Pages, and the `revalidate` option on `fetch` doesn't trigger on-demand revalidation the way it does on Vercel. A common replacement pattern is:

- Cache API responses in Cloudflare KV with a short TTL.
- Purge the relevant KV key via a webhook when the underlying data changes.
- Have server components read from KV first, falling back to the origin database.

This works, but it trades away the simplicity of `revalidate` tags for manually managed cache invalidation.

### Server Components and Streaming

Server components generally work on Cloudflare Pages, with the caveat that any library depending on Node.js built-ins needs a Web-Crypto-compatible or edge-compatible replacement — for example, swapping `bcrypt` for a Web Crypto–based hashing library, `sharp` for Cloudflare's Image Resizing, and `uuid` for `crypto.randomUUID()`.

Streaming with `Suspense` boundaries works without special handling, which makes it practical to stream real-time data from a Cloudflare Worker into the page without standing up a separate WebSocket server.

### Middleware and Authentication

Next.js middleware runs on the edge, but authentication flows built around a session cookie verified by a Node.js backend (e.g., `express-session`) need to change. A common approach is switching to JWTs verified with `crypto.subtle.verify()` (Web Crypto), with middleware reading the token from the `Authorization` header, verifying it against a public key stored in KV, and attaching user context to the request.

The trade-off is losing straightforward server-side session revocation — teams typically compensate with short-lived tokens and a refresh-token flow.

### Build and Deployment

Build times tend to increase somewhat versus a standard Next.js build, since the adapter has to run compatibility checks and transform Node.js imports. Deployment itself, using `wrangler pages deploy`, tends to be fast, which makes frequent same-day deploys practical.

## Trade-Offs to Accept

No architecture is free of trade-offs. Keeping a Next.js product unified on Cloudflare generally means giving up:

- **Full Node.js compatibility.** Any library that uses `fs`, `net`, `child_process`, or non-standard `process.env` access will need to be forked or replaced.
- **ISR as designed.** A custom KV-based caching layer works, but it's more code to maintain than built-in ISR.
- **The Pages Router's `getServerSideProps`.** This isn't supported on Cloudflare's edge runtime, so migrating means moving fully to the App Router with server components.
- **Local file system access.** File uploads need to move to object storage such as Cloudflare R2, handled via Workers.

For a data-heavy dashboard with moderate traffic, these trade-offs are often acceptable. For a mostly-static site or blog, the unified approach is close to trivial. For a real-time multiplayer application or heavy file-processing workload, splitting the architecture is more likely to be the right call.

## Takeaway

**Direct answer:** Shipping Next.js on Cloudflare without splitting the product apart is a practical option for teams that want a single codebase and want to use the edge without taking on extra operational complexity — provided the team is willing to adopt edge-first patterns from the start.

- Use Web APIs instead of Node.js built-ins wherever possible.
- Replace ISR with a cache layer built on KV, D1, or a Worker-based cache.
- Keep authentication stateless (JWTs rather than server-side sessions).
- Test middleware and server components against the edge runtime early, rather than late in the migration.

The unified path is narrower than a split architecture, and it asks more of the team up front, but for many small-to-mid-size SaaS products it leads to a simpler, cheaper deployment to maintain going forward — as long as the team doesn't have legacy Node.js dependencies that can't reasonably be replaced.

## Evidence and scope

**Review date:** 2026-09-10.

**Reproducible use.** Use the framework with a defined audience, source data, and review date; test material recommendations against your own evidence before making a production or buying decision.

**Limit.** This article is educational guidance, not legal, financial, security, or performance assurance.

