Deployment β static#
Default target is pure-static, deployed by Git build. Choose the host at kickoff and record it; every later step refers to "the production host."
| Target | When |
|---|---|
| Cloudflare Workers static assets | preferred Cloudflare target for new projects |
| Cloudflare Pages | supported; existing projects stay put |
| Netlify static hosting | equally supported |
- Both hosts: build command
npm run build, outputdist/. - Stay adapter-free for static sites so Astro's Sharp image service runs at build. Keep
output: 'static', no adapter. An SSR adapter is only for SSR. - Per-host config (the only real difference):
- Cloudflare β
wrangler.jsonc:assets.directory: "./dist", nomainWorker,compatibility_flags: ["nodejs_compat"],observability.enabled. - Netlify β
netlify.toml:[build] command = "npm run build",publish = "dist".
- Cloudflare β
- Redirects β portable. Ship
public/_redirects; both hosts read the same format (/old /new 301). Essential for migrations: map every old URL to its new path so link equity survives the cutover. - Headers & caching β portable. Ship
public/_headers:/_astro/*getsCache-Control: public, max-age=31536000, immutable(hashed filenames), plus baseline security headers (X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin, a conservative CSP). Remember these apply to production (seo.staging). - Forms β a separate function/Worker with an email binding (components.forms).
- Demo/showcase routes are gated, not deleted.
/styleguide,/componentsand previews live insrc/demos/, injected by an integration only inastro devor whenSHOW_DEMOS=true. The client keeps the full showcase locally; production deploys without it.