// hosting
How to host an Astro site: static and SSR options
A practical guide to deploying an Astro site — the difference between static output and server (SSR) output, how adapters work, the build commands, and how to choose a host for each mode.
Astro can ship your site two very different ways, and which one you pick decides where and how you host it. By default Astro builds a folder of plain HTML, CSS and JS — files any static host can serve. But Astro can also run on a server, rendering pages on demand (SSR) for things like authentication, forms or per-request data. This guide explains both output modes, the build commands behind them, how adapters fit in, and how to choose a host for each.
Static vs server: the core decision
Every hosting choice for Astro flows from one question: does your site need a running server at request time?
- Static (the default). Pages are rendered once, at build time, into HTML files. There's no server process — you upload the built folder to a CDN or static host and it serves files. Fastest, cheapest, simplest. Ideal for blogs, docs, marketing sites and most content sites.
- Server / SSR. Pages are rendered per request by a Node (or edge) process. Needed when content depends on the request: logged-in users, form handling, on-the-fly personalisation, or data that must be fresh on every load.
You can also mix the two: keep the site mostly static and opt specific routes into on-demand rendering. The point is to render statically wherever you can, and only pay for a server where you actually need one.
The build commands
Whatever the mode, the workflow is the same two commands — install, then build:
# install dependencies
npm install
# produce the production build
npm run build
# preview the production build locally before deploying
npm run preview By default npm run build writes a static site to the dist/ folder. That folder is your entire deployable site in static mode — there is nothing else to run.
Configuring the output mode
You control the mode in astro.config.mjs. Static is the default, so a minimal config needs nothing special. To render on the server, you add an adapter — a small package that teaches Astro how to run on a specific platform (Node, or an edge/serverless runtime):
// astro.config.mjs — server (SSR) output with the Node adapter
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
}); With the standalone Node adapter, npm run build produces a server entry point you start like any Node app:
# after building with the Node adapter
node ./dist/server/entry.mjs If you only need a handful of dynamic routes, keep the default static output and opt individual pages out of prerendering instead of switching the whole site to server mode:
---
// src/pages/dashboard.astro — render this page per request
export const prerender = false;
---
Choosing a host by mode
Static hosting
For static output you just need somewhere to serve the contents of dist/ over HTTPS, ideally from a CDN. The build/publish settings are simple:
Build command: npm run build
Publish/output: dist Plenty of platforms do this — managed static hosts, object storage behind a CDN, or a general-purpose host that can serve a folder. Because there's no server to keep alive, static hosting is cheap and effortless to scale. Hosting on European infrastructure is a fine choice here when your audience or data-residency needs point that way.
Server (SSR) hosting
SSR needs a runtime that keeps a process alive. Two broad routes:
- A Node host / VPS. With the Node adapter you build a standalone server and run it like any Node service. A VPS gives you full control over the process, environment and scaling — handy if you already run other services there.
- Serverless / edge. Platform-specific adapters package your app to run as functions. Less to manage, but you're tied to that platform's model.
A simple way to run the Node build on your own server is a process manager so it restarts on crash or reboot:
# example: keep the Astro Node server running with PM2
npm install -g pm2
pm2 start ./dist/server/entry.mjs --name astro-site
pm2 save Quick reference
| Need | Mode | What to host |
|---|---|---|
| Blog, docs, marketing, content | Static (default) | The dist/ folder on a CDN/static host |
| Mostly static, a few dynamic routes | Static + prerender = false per page | A host/adapter that supports on-demand routes |
| Auth, forms, per-request data everywhere | Server (SSR) | A Node runtime / VPS or serverless platform |
How to decide
Start static — it's the default for a reason: cheaper, faster and simpler to host. Only reach for the server adapter when a real requirement (logged-in state, form processing, always-fresh data) forces per-request rendering, and even then consider opting just those routes out of prerendering rather than running the whole site on a server. Match the host to the mode you end up with: a CDN-backed static host for built files, or a Node-capable VPS / serverless platform when you genuinely need a server.