Direct Cloudflare Pages API upload. 300+ edge PoPs, free tier covers most sites. The fastest path for pure-static content worldwide.
What it is
Cloudflare Pages (direct) pushes your built site to Cloudflare's edge network via the Direct Upload API. No git push, no webhook relay, no wrangler CLI — just an HTTPS upload. Cloudflare serves the files from 300+ PoPs worldwide with automatic HTTPS and unlimited bandwidth on the free tier.
This replaces the legacy
Cloudflare (webhook)provider, which only POSTed to a build hook URL. That one still exists for backwards compatibility, but new sites should pickCloudflare Pages (direct).
When to use it
- Your site is static (no SSR, no custom server logic)
- You want the fastest possible first-byte time globally (10–30 ms at edge)
- You want the lowest cost ($0 on free tier for typical small sites)
- You're OK with Cloudflare as a dependency (DNS optional, project can still use any registrar)
When NOT to use it
- Your site is a Next.js SSR app — use Vercel, Fly.io (rebuild), or Cloudflare Workers.
- You need write-at-runtime content storage (uploads, form submissions) — Pages is immutable static.
- You're already committed to Fly for other services and want one hosting provider — use Fly.io Live.
How it works
- CMS admin builds your site locally (
deploy/) - Posts all files as
multipart/form-datatoPOST /accounts/:id/pages/projects/:name/deployments - Cloudflare processes the upload, creates a new deployment, and propagates to the edge
- The new version is live globally in ~3–10 seconds
On first deploy, the admin automatically creates the Pages project (type: Direct Upload). Subsequent deploys just add new deployments to the existing project.
Setup
1. Get your Cloudflare credentials
Account ID — Cloudflare dashboard → select any domain → right sidebar, copy the Account ID.
API token — Cloudflare dashboard → My Profile → API Tokens → Create Token → Custom token with:
- Permissions: Account → Cloudflare Pages → Edit
- Account resources: Include → your account
No other scopes are needed. Save the token securely — it won't be shown again.
2. Configure the provider
Settings → Deploy → Cloudflare Pages (direct). Provide:
- API token — from step 1
- Account ID — from step 1
- Project name — lowercase, digits, hyphens (e.g.
my-site). Auto-generated from your site name if left empty. Max 58 characters.
3. Click Deploy
First click creates the Cloudflare Pages project and uploads your files. You'll see the live URL: https://<project-name>.pages.dev (or your custom domain if configured).
4. Custom domain (optional)
Cloudflare dashboard → Pages → your project → Custom domains → Set up a custom domain. Cloudflare handles DNS + certs automatically.
Payload format
The upload uses multipart form-data. Field names are paths with leading slash (e.g. /index.html, /assets/app.js). Binary files are sent as-is — Cloudflare handles content-type detection.
There's no HMAC signing on this provider — Cloudflare uses your Bearer token directly. Keep the token secret.
Rollback
In the Cloudflare dashboard, each deployment is listed under Pages → your project → Deployments. Click any historical deployment → Rollback. The Pages URL updates immediately.
The CMS admin doesn't expose Cloudflare rollback in UI yet — use the dashboard for now.
Limits (free tier)
- 500 builds per month — a build = one deploy. Most sites do 10–30/month.
- Unlimited requests — no bandwidth caps.
- 25 MB per file — large videos should go to R2 or another CDN.
- 20 000 files per deployment — enough for any normal site.
Paid Pro ($20/mo) raises the build limit to 5000/month. Most small sites never need to pay.
Comparison
| Cloudflare Pages | Fly.io Live | GitHub Pages | Vercel | |
|---|---|---|---|---|
| Time per deploy | 3–10 s | 200 ms–1 s | 15–30 s | 20–60 s |
| Global edge | Yes (300+ PoPs) | No | Yes (CDN) | Yes (Edge) |
| Free tier | Generous | No | Yes | Yes (Hobby) |
| SSR support | Workers (separate) | No | No | Yes |
| Custom domain | Free, easy | Flyctl, requires DNS | Subpath friendly | Free |
Troubleshooting
"project name invalid" — project names must be lowercase letters, digits, and hyphens (max 58 chars). The admin slugifies your site name — if that fails, enter a valid name manually.
"deployment rejected" — Cloudflare returns a reason in the error. Common causes: oversized file (>25 MB), too many files (>20k), expired token.
"account ID missing" — copy the Account ID exactly from the Cloudflare dashboard. It's 32 hex characters.
Related
- Fly.io Live — when you want everything on Fly
- Deploy settings — full provider reference
- Instant Content Deployment — the push-to-running-Next.js pattern, not relevant for static sites on Pages