Deploy a site
Build a site for Netlify, Cloudflare Workers, Vercel, your own Node server or any static host.
Every target is one build script. Pages and share cards always prerender. On an adapter build, /preview (the CMS's live preview), /api/contact (the contact form's handler) and /map/[point].png (when a Google map key is set) run on demand. Routes lists them all.
| Target | Script | Adapter | Output |
|---|---|---|---|
| Netlify | pnpm build |
@astrojs/netlify, preinstalled |
dist/ plus a function under .netlify/v1/ |
| Cloudflare Workers | pnpm build:cloudflare |
@astrojs/cloudflare, preinstalled |
dist/client/ and dist/server/wrangler.json |
| Vercel | pnpm build:vercel |
@astrojs/vercel, add it first |
the adapter's output |
| Node server | pnpm build:node |
@astrojs/node, add it first |
a standalone server in dist/ |
| Static host | pnpm build:static |
none | a fully static dist/ |
A target whose adapter is missing stops the build with the command that installs it.
Netlify
- Connect the repository in Netlify, with build command
pnpm buildand publish directorydist. From the command line, usenetlify deployinstead. - Set
RESEND_API_KEY,CONTACT_FROMandCONTACT_TOin the site's environment, so the contact form delivers. See Connect the contact form. - Deploy. The contact handler and the CMS preview ship as a serverless function on their own; open
/previewon the deployed site and it answers.
Cloudflare Workers
Build for Workers.
pnpm build:cloudflareDeploy with the config the build wrote.
npx wrangler deploy -c dist/server/wrangler.jsonOpen the URL wrangler prints. When
siteinastro.config.mjsnames a real host, a page opened on the*.workers.devaddress redirects to the same path there. Whensiteis itself a*.workers.devor*.pages.devaddress, every page is built withnoindex.
Set RESEND_API_KEY, CONTACT_FROM and CONTACT_TO as the Worker's variables or secrets; /api/contact reads the Worker's bindings first. To rate-limit the form, bind a KV namespace as STOMME_RL in the site's wrangler config at its root, such as wrangler.jsonc:
{
"kv_namespaces": [{ "binding": "STOMME_RL", "id": "<namespace id>" }]
}
With it bound, the handler answers 429 after five messages from one visitor in ten minutes. See Connect the contact form.
If the site uses Cloudflare Web Analytics, set analytics.cfToken. See Measure visits.
Vercel
Add the adapter.
pnpm add @astrojs/vercelBuild.
pnpm build:vercelDeploy the output with the Vercel CLI or a connected repository using that build command.
Your own Node server
Add the adapter.
pnpm add @astrojs/nodeBuild. The adapter runs in standalone mode, so the output is a server you start with Node.
pnpm build:nodeStart the server from the build output and open the site on the port it prints.
node dist/server/entry.mjs
A static host
Build without an adapter.
pnpm build:staticUpload
dist/to any host that serves files, such as GitHub Pages.Open the site.
/previewis prerendered, so the CMS preview does not follow typing, and/api/contactdoes not exist. Point the form at your own handler withcontact.endpoint, see Connect the contact form.
The engine's links start at the domain's root, such as /contact/, and do not follow Astro's base option. Serve the site from the root of its host: on GitHub Pages, a user or organisation site (user.github.io) or a custom domain, not a project site under user.github.io/repo.
Set the site's address
Set site in astro.config.mjs to the address the site is served on. Canonical URLs, Open Graph URLs, hreflang links, the sitemap and the Sitemap: line in robots.txt are built from it.
export default defineConfig({
site: 'https://example.com',
// …
});