Cloudflare Pages Env Vars Missing at Build Time (Not Runtime)
Astro PUBLIC_ vars work in dev but undefined during CF Pages build. Set production vs preview env and avoid wrangler.toml pitfalls.
Stack: Astro 5 static, deployed to Cloudflare Pages Error in build log:
[SITE_URL] is required but was undefined during static generation
Worked locally with .env. Failed on CF Pages.
TL;DR
- CF Pages injects env at build time for static prerender — not just runtime.
- Set vars for Production AND Preview in dashboard.
- Use PUBLIC_ prefix for client-exposed Astro/Vite vars.
Cloudflare Pages env UI
Dashboard → Pages → project → Settings → Environment variables
Scopes:
- Production
- Preview (PR previews)
- Can add plaintext or secret
I only set Production. Preview builds on PRs failed.
Astro public vs private
# Available in client bundle — must be set at BUILD time
PUBLIC_SITE_URL=https://example.com
# Server-only — not inlined
API_SECRET=xxx
Static export inlines PUBLIC_* during astro build. If missing at build → empty string in output.
wrangler.toml (optional binding)
name = "my-blog"
pages_build_output_dir = "dist"
[vars]
PUBLIC_SITE_URL = "https://example.com"
Don't commit secrets to wrangler.toml. Use dashboard for secrets.
Fix workflow
- Add
PUBLIC_SITE_URLfor Production AND Preview in dashboard - Retry deployment (Deployments → ... → Retry)
- Verify built HTML:
curl https://preview-abc.pages.dev | rg 'example.com'
Different values per environment
Preview can use:
PUBLIC_SITE_URL=https://preview-abc.pages.dev
Set via Preview-specific variable — overrides production on preview branches.
Local parity
# .dev.vars for wrangler pages dev
PUBLIC_SITE_URL=http://localhost:8788
Lesson
Static site "runtime env vars" don't exist. Everything public is baked at build. Plan accordingly.
CI check for missing PUBLIC vars
# .github/workflows/pages.yml
- name: Build
env:
PUBLIC_SITE_URL: https://example.com
run: npm run build
Mirror dashboard vars in CI so local Actions match Cloudflare dashboard — avoids "works in dashboard, fails on manual retry".
Wrangler pages dev
npx wrangler pages dev dist --compatibility-date=2024-01-01
Serves built dist/ with .dev.vars loaded — closest local parity to production build.
FAQ
Why are env vars undefined during Cloudflare Pages build?
Vars may only be set for Production, not Preview. Or Astro/Vite needs PUBLIC_ prefix for client-side access during prerender.
Build-time vs runtime env on Cloudflare Pages?
Static sites prerender at build — anything embedded in HTML must exist at build time. Functions-only vars won't help static prerender.
Does wrangler.toml affect Pages build env?
Pages uses dashboard env primarily. wrangler.toml [vars] can conflict or be ignored depending on setup — prefer dashboard for Pages.