Next.js on Cloudflare works well when you treat environment variables and build settings like real infrastructure. It gets painful when you wing it, push from a laptop with twelve ghost env files, and then wonder why production is serving yesterday’s secrets.
Here is the habit stack that keeps deploys boring.
Start with one mental model
Cloudflare Pages for the Next.js app shell. Cloudflare Workers when you need edge logic, middleware-style behavior, or API routes that benefit from being close to the user. Bindings for KV, D1, R2, or queues when the job actually needs them.
Do not invent a micro-architecture because a blog post had a cool diagram. Ship the smallest thing that matches your traffic and your brain.
A solid default for a personal or small product site is boring: Pages project, preview deployments on PRs, production pinned to main, env vars scoped per environment.
Env discipline is the whole game
Most Cloudflare pain is env related.
Rules worth following:
- Never put production secrets in a local `.env` that also gets copied into screenshots or chat logs.
- Name variables the same across preview and production when possible. Different values, same keys.
- Document required vars in the repo in a `.env.example` with dummy values only.
- Fail the build if a required var is missing. Silent undefined is how you ship a half-dead site.
- Rotate anything that ever appeared in a failed deploy log.
Keep a short note in the README: which vars are public (NEXT_PUBLIC_*) and which are server only. Mixing those up is a classic footgun.
Preview deployments save friendships
If you are collaborating with anyone, including future you, preview URLs matter.
Treat previews as real environments. Give them their own env set. Point them at non-production data when that is an option. Click around before you merge.
Open the preview on your phone, not just your desktop. Mobile layout bugs and cookie weirdness love to hide until you are away from the keyboard.
Build settings to stop tweaking every week
Chasing the perfect Node version, install command, and output directory ritual is a trap.
Lock these instead:
- Node version explicitly
- Install command that matches the lockfile
- Build command that is identical in CI and Cloudflare
- Output expectations documented once
If a deploy fails, check three things first: lockfile drift, missing env, and “works on my machine” path assumptions. That order fixes most of it.
Workers patterns to keep small
When you add a Worker in front of or beside the app, keep the surface tiny.
- Auth gate or geo-aware redirect? Fine.
- Rewrite a handful of paths? Fine.
- Reimplement half the app in the Worker because edge is trendy? No.
Caching headers and CDN behavior can do a lot before you write custom edge code. Write Workers when you have a specific behavior you can name in one sentence.
Logging and rollback without drama
Keep two questions in your head at all times:
- What is live right now?
- How do I go back one version?
Cloudflare makes rollback possible. Your habits make rollback calm. Tag releases. Keep notes on what changed. Do not stack five unrelated changes into one deploy because you were already in there.
Watch the first ten minutes after a production push. Latency spikes, 500s, and wrong env values announce themselves early if you are looking.
A practical checklist before you hit deploy
- Preview looks right on desktop and phone
- Required env vars present in the target environment
- No secrets in client bundles
- Redirects and trailing-slash behavior match what SEO expects
- Analytics or error reporting still receiving events
- You know how to roll back
If any box is unchecked, wait. Waiting is cheaper than debugging at dinner.
Why Cloudflare stays useful
Speed, decent DX for static and hybrid apps, and a security posture that does not require babysitting a VPS for every brochure site. Homelab stuff can stay on metal you own. Public web apps do not need your basement to be a single point of failure.
Bottom line
Next.js on Cloudflare works when you respect the platform boundaries and keep env hygiene boring. Boring wins. Flashy architecture posts do not answer your pager.
If your deploy process depends on remembering which laptop has the right .env.local, you do not have a process. You have a superstition. Write the keys down. Scope them. Preview them. Then deploy like someone who wants to sleep.


