Skip to main content
DevOps6 min readMarch 3, 2026

Cloudflare Pages: The Fastest Way to Deploy Your Frontend

A complete guide to Cloudflare Pages for frontend deployment — setup, Workers integration, custom domains, and performance optimization strategies.

James Ross Jr.

James Ross Jr.

Strategic Systems Architect & Enterprise Software Developer

Cloudflare Pages: The Fastest Way to Deploy Your Frontend

I run a lot of client frontends on Cloudflare Pages. Not because it is the trendiest choice, but because the performance numbers are genuinely hard to argue with. Cloudflare's network spans 300-plus points of presence worldwide. When a user in Sydney requests your static site, they are hitting a Cloudflare edge node in Sydney, not crossing the Pacific to your origin server. Time to first byte under 50ms is the baseline, not the aspirational target.

For static frontends and Nuxt/Next.js applications with server-side logic running on Cloudflare Workers, Pages is my default recommendation. Here is how to set it up correctly.

Connecting Your Repository

The starting point is straightforward. In your Cloudflare dashboard, navigate to Pages > Create a project > Connect to Git. Authenticate with GitHub or GitLab, select your repository, and configure the build settings.

Cloudflare has preset configurations for common frameworks. Select your framework and the build command and output directory auto-populate. For a Nuxt 3 app:

  • Build command: npm run build
  • Output directory: .output/public

For a Vite React app:

  • Build command: npm run build
  • Output directory: dist

The first build runs immediately. Every subsequent push to your configured production branch triggers a new deployment. Every pull request gets a preview deployment with a unique URL — the same developer experience as Vercel, without the premium pricing.

Environment Variables and Secrets

Set environment variables under your project's Settings > Environment variables. Cloudflare differentiates between plain-text variables and encrypted secrets. Secrets are masked in logs and inaccessible after setting — you can only override them, not view them.

Scope variables to production or preview environments. Your API_BASE_URL for production should point to your production API. For preview deployments, point it at staging. This prevents preview branches from accidentally hitting production APIs with test data.

One important difference from Vercel: Cloudflare Pages environment variables are available at build time and, with Workers, at runtime. For purely static sites, runtime environment variables do not exist — there is no server to read them. Variables used in your JavaScript bundle must be inlined at build time, which means they end up in your built assets. Do not put secrets in build-time variables for static sites. Secrets belong server-side.

Cloudflare Workers for Server-Side Logic

The compelling reason to choose Cloudflare Pages over a traditional CDN is Workers integration. You can run server-side logic at the edge using Cloudflare Workers, eliminating cold starts and keeping compute geographically close to your users.

Create a functions/ directory in your project root. Files in this directory become Workers that handle requests. A functions/api/user.ts file handles requests to /api/user.

// functions/api/user.ts
export const onRequest: PagesFunction<Env> = async (context) => {
  const { request, env } = context;

  if (request.method !== "GET") {
    return new Response("Method not allowed", { status: 405 });
  }

  // Access D1 database, KV store, or external APIs here
  const userData = await env.DB.prepare("SELECT * FROM users LIMIT 10").all();

  return Response.json(userData.results);
};

Workers run in Cloudflare's V8 isolate environment — not Node.js. This means Node-specific APIs are not available. The Workers runtime supports the Fetch API, Web Crypto, Streams, and most modern browser APIs. Libraries that depend on Node internals (fs, crypto from Node, native buffers) need to be substituted with Workers-compatible alternatives.

KV, D1, and R2: The Cloudflare Storage Stack

If your application needs storage and you are already on Cloudflare, using their native storage options removes network hops to external services.

KV (Key-Value) is globally distributed storage for configuration, sessions, and cached data. Reads are fast from anywhere in the world. Writes are eventually consistent — a write in one region takes up to 60 seconds to propagate everywhere. Use KV for data that changes infrequently: feature flags, site configuration, cached API responses.

D1 is Cloudflare's SQLite-based relational database. For read-heavy workloads with standard SQL queries, D1 is excellent and the pricing is extremely competitive. For write-heavy applications or complex query patterns, evaluate carefully — D1 is still maturing. Migrations run via Wrangler CLI: wrangler d1 migrations apply my-db.

R2 is object storage compatible with the S3 API. Store user uploads, generated PDFs, static assets too large for KV. R2 has no egress fees — a significant cost advantage over S3 for bandwidth-heavy applications.

Custom Domains

Adding a custom domain to Cloudflare Pages is smooth when your domain is already managed by Cloudflare DNS, and slightly more involved when it is not.

For domains already on Cloudflare: Pages > Custom domains > Add domain, type your domain, done. Cloudflare creates the DNS records automatically.

For external DNS: you will get a CNAME target to add to your registrar. Create a CNAME record for your subdomain (or use @ for apex domains that support CNAME flattening). SSL is handled automatically via Cloudflare's certificate authority.

For apex domains (yourdomain.com without www), Cloudflare supports CNAME flattening, which lets you point your root domain at a CNAME target. Most DNS providers do not support this — it is a Cloudflare-specific feature. If you want to use an apex domain without migrating to Cloudflare DNS, you are limited to providers that support ALIAS or ANAME records.

Build Caching and Performance

Cloudflare Pages caches node_modules between builds based on your lockfile. This is automatic and generally works well. Where you can improve build times further is by minimizing what you install.

Use npm ci rather than npm install in your build commands. Install only production dependencies for production builds when your framework supports it. For Nuxt specifically, the build output in .output/ includes everything the runtime needs — you do not need to install dev dependencies in production.

For large monorepos, Cloudflare Pages supports specifying a root directory for your application. Set this under project settings to point at your frontend package. Builds only trigger when files within that directory change.

Handling Redirects and Headers

Manage redirects and custom headers using a _redirects file and a _headers file in your build output directory.

# _redirects
/old-path  /new-path  301
/api/*     https://api.yourdomain.com/:splat  200
# _headers
/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()

The _headers file lets you set security headers across your entire site without touching your Workers code. Place these in your public directory or configure your build tool to output them to the build directory.

When to Choose Pages Over Vercel

The honest answer depends on your stack and your constraints. If you are running Next.js with heavy use of Next-specific features (ISR, App Router server components, image optimization), Vercel's tight integration with Next.js is a real advantage. If you are running Nuxt, SvelteKit, or a framework-agnostic Vite build, Cloudflare Pages performs at least as well and often cheaper at scale.

The pricing difference matters at volume. Cloudflare Pages is free for unlimited deployments and generous free tier bandwidth. Vercel's free tier is more restrictive, and commercial features add up quickly. For agencies deploying many client sites, Cloudflare's pricing model is meaningfully better.

The developer experience is excellent on both platforms. The infrastructure performance is excellent on both platforms. Choose based on your framework, your storage needs, and your budget.


If you want help evaluating deployment options for your specific frontend stack, I am happy to work through it with you. Book a call at https://calendly.com/jamesrossjr.


Keep Reading