Astro Build Standards docs

Deployment β€” static#

[deploy.static]Required

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."

TargetWhen
Cloudflare Workers static assetspreferred Cloudflare target for new projects
Cloudflare Pagessupported; existing projects stay put
Netlify static hostingequally supported
  • Both hosts: build command npm run build, output dist/.
  • 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", no main Worker, compatibility_flags: ["nodejs_compat"], observability.enabled.
    • Netlify β†’ netlify.toml: [build] command = "npm run build", publish = "dist".
  • 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/* gets Cache-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, /components and previews live in src/demos/, injected by an integration only in astro dev or when SHOW_DEMOS=true. The client keeps the full showcase locally; production deploys without it.