← Labs
Deployment Updated May 4, 2026

Deploying to Cloudflare Pages

A structured walkthrough for shipping static sites with Wrangler CLI, branch deploys, and zero-downtime rollbacks.


This is the runbook I wish existed when I set up korfe.org. Cloudflare Pages is excellent infrastructure, but the docs assume you already know how the pieces fit together. This walkthrough does not.

Prerequisites

  • A Cloudflare account with a zone (domain) attached
  • Wrangler CLI installed: npm install -g wrangler
  • An API token with Cloudflare Pages: Edit permissions

Store your token in a .env file at your project root:

CF_API_TOKEN=your_token_here

Project structure

Cloudflare Pages expects a dist/ output directory and an optional functions/ directory for serverless functions. Critical: Wrangler resolves functions/ relative to your current working directory, not relative to dist/. Always run deploy commands from the directory that contains functions/.

your-project/
  site/
    dist/          ← build output
    functions/     ← serverless functions
    package.json

Build and deploy

cd your-project/site

# Build
npm run build

# Deploy to preview
CLOUDFLARE_API_TOKEN=$CF_API_TOKEN npx wrangler pages deploy dist \
  --project-name your-project-name

# Deploy to production
CLOUDFLARE_API_TOKEN=$CF_API_TOKEN npx wrangler pages deploy dist \
  --project-name your-project-name \
  --branch=main

The --branch=main flag is what triggers a production deployment. Without it, every deploy goes to a unique preview URL.

Branch deploys

Every deploy without --branch=main creates a preview URL at a subdomain of your Pages project. You can also set up a persistent alias:

In the Cloudflare dashboard, go to Pages → your project → Custom domains and add dev.yourdomain.com pointing to your preview branch.

Environment variables

Set secrets in the Cloudflare dashboard under Pages → Settings → Environment variables. These are available at runtime in functions/ via context.env.YOUR_VAR.

Do not commit secrets to your repo. Do not put them in wrangler.toml.

Rollbacks

Every Cloudflare Pages deployment is retained and can be re-activated instantly from the dashboard. If a production deploy breaks something:

  1. Go to Pages → your project → Deployments
  2. Find the last known-good deployment
  3. Click Retry deployment (this re-promotes it to production)

This is zero-downtime. The old deployment stays live until the re-promotion completes.

Common gotcha: working directory

If your functions aren’t running in production but your static pages are, the likely cause is deploying from the wrong directory. Wrangler uploads functions/ from wherever you run the command — if it doesn’t find a functions/ folder there, it silently skips it.

Always cd into the directory that contains both dist/ and functions/ before deploying.