Deploying to Cloudflare Pages
Deploy your site to Cloudflare Pages with a practical view of build commands, environment variables, preview environments, rollback, and common failure modes.
When is Cloudflare Pages a good fit?
If your project is a static site or a frontend application that can be exported as static assets, Cloudflare Pages is often a very low-friction deployment target. Its value is not only the CDN. It also packages together:
- Git-driven automatic deployments,
- preview environments for branches or PRs,
- global edge distribution,
- HTTPS and rollback behavior,
- and integration with the broader Cloudflare ecosystem.
That said, if your application depends on heavy backend logic, long-lived connections, or private-network access, Pages may not be the whole solution.
What should you verify before starting?
Before connecting a project to Cloudflare Pages, confirm:
- the project can reliably produce a static build,
- the build command already works locally,
- you know which variables are public config and which are secrets,
- preview and production environments need the right separation,
- your team knows how deployment failures will be investigated.
Getting this clear upfront saves a lot of debugging time later.
A realistic deployment flow
Step 1: Make the local build pass first
Do not start in the dashboard and guess later. First validate the build locally:
pnpm install
pnpm buildAt minimum, know:
- what the output directory is,
- which environment variables the build depends on,
- whether there are post-build steps such as indexing, compression, or static search generation.
Step 2: Connect the Git repository
The typical Cloudflare Pages flow looks like this:
1. sign in to Cloudflare Dashboard,
2. open Workers & Pages,
3. create a Pages project,
4. connect the GitHub repository,
5. choose the branch that should auto-deploy.
The most important decisions are not the clicks. They are:
- which branch represents production,
- whether feature branches get previews,
- who is allowed to trigger production changes.
How should you think about build configuration?
Whether you configure everything in the dashboard or in project config, the fundamentals stay the same:
- build command,
- output directory,
- environment variables.
The snippet below is an illustrative example that explains common config concepts. It should not be treated as the one correct wrangler.toml for every project.
name = "my-site"
compatibility_date = "2026-03-01"
[build]
command = "pnpm build"
[site]
bucket = "./dist"In real deployments, defer to your actual framework and Cloudflare's current supported configuration model.
How should environment variables be separated?
This is one of the most common failure points.
At a minimum, split them into two classes.
Public build configuration
Examples:
- public API endpoints,
- feature flags,
- analytics IDs.
Sensitive variables
Examples:
- LLM API keys,
- database connection strings,
- private service tokens.
The rule is simple:
- if it can live as a secret, do not hardcode it,
- preview and production should be managed separately where needed,
- local
.env, CI secrets, and Cloudflare secrets should follow the same meaning.
Why do preview environments matter?
Many deployment problems appear only in a real hosted build environment, such as:
- missing production-only variables,
- route behavior that differs from local dev mode,
- broken asset paths under preview URLs,
- third-party callbacks tied to allowed domains.
If your team frequently changes frontend behavior, content, config, or SEO, preview deployments are close to mandatory.
What should CI/CD focus on?
The key question is not just whether you use GitHub Actions. It is whether the deployment path is explicit:
- which branch triggers production,
- whether pull requests trigger preview builds,
- whether lint, typecheck, and build run before deployment,
- where people look when a deployment fails.
A common healthy path is:
1. run validation in PRs,
2. publish a preview build for review,
3. deploy production on merge to main,
4. keep rollback available when something breaks.
Common troubleshooting patterns
1. It builds locally but fails in Cloudflare
Check first:
- Node.js version differences,
- lockfile consistency,
- variables that only exist locally,
- build scripts that assume local files or local paths.
2. The deployment succeeds but the site is wrong
Check first:
- whether the output directory is correct,
- whether static asset base paths are correct,
- whether SSR / SPA / static export assumptions match the site setup,
- whether redirects or rewrites override expected routes.
3. Preview works but production breaks
Check first:
- missing production variables,
- domain binding status,
- third-party allowlists that only include preview domains,
- stale cache serving an older deployment.
A practical acceptance checklist
Before saying “deployment is done,” verify:
- [ ] the local build already passes,
- [ ] the Cloudflare build command and output directory are correct,
- [ ] preview and production variables are clearly separated,
- [ ] the production domain works,
- [ ] the team knows how to inspect logs and roll back,
- [ ] static assets, routes, and core SEO behavior are intact.
What to read next
- If the site will later integrate agent workflows, return to Getting Started with OpenClaw
- If you want to automate deployment behavior inside reusable agent capabilities, pair this with Building Custom Skills
- If the system is growing toward knowledge-assisted answering, continue with the RAG System Implementation Guide