The official Cloudflare adapter for Astro (@astrojs/cloudflare) is designed for SSR. If your Astro site is fully static — output: 'static' — you don’t need it. In fact, using it for a static site causes a chicken-and-egg build error.
Here’s the clean approach: Workers static assets.
How it works
Cloudflare Workers supports serving static files directly from a dist/ directory via the assets configuration key. No adapter needed, no SSR middleware, no complexity:
astro buildoutputs todist/wrangler deployuploadsdist/to Cloudflare’s edge network- Worker requests are handled by the static asset handler automatically
Setup
Install wrangler:
npm install -D wrangler
Create wrangler.jsonc:
{
"name": "my-site",
"compatibility_date": "2026-03-01",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": "./dist"
},
"observability": {
"enabled": true
}
}
That’s the entire configuration. No main field, no Worker script — just the static assets binding.
Add scripts to package.json:
{
"scripts": {
"build": "astro build",
"deploy": "wrangler deploy",
"preview": "astro build && wrangler dev"
}
}
GitHub integration
The Cloudflare dashboard has a native GitHub integration that automatically builds and deploys on push. For a static Astro site, configure it as:
- Build command:
npm run build - Build output:
dist - Framework preset: Astro
When you push to main, Cloudflare builds and deploys to production. For pull requests, it creates a preview deployment with a unique URL — great for review.
Preview URLs
Every branch push gets a preview URL in the format:
https://<branch-dashes>-<worker-name>.<subdomain>.workers.dev
For example, a branch feat/dark-mode on a Worker named my-site under user subdomain:
https://feat-dark-mode-my-site.user.workers.dev
Cloudflare posts this URL as a GitHub check run. Extract it programmatically:
gh api repos/OWNER/REPO/commits/$SHA/check-runs \
--jq '.check_runs[] | select(.name | startswith("Workers")) | .output.summary' \
| grep "Preview Alias URL"
Caveats
SPA routing: Static assets doesn’t support SPA-style client-side routing without a Worker script. If you need that, add a _worker.js or use the proper adapter.
Edge functions: If you need server-side logic (API routes, auth), you need @astrojs/cloudflare. Static assets is for fully-static sites only.
Custom domains: Configure in the Cloudflare Workers dashboard under Settings → Domains & Routes.
For a personal site or blog — static is almost always the right call. Keep it simple.