Static Astro fits; SSR adapters do not
Astro can emit a pure static site or wire an SSR adapter (Node, serverless targets, etc.). StaticHost accepts the static output only. If your astro.config uses an SSR adapter, you need an application host. If you use the default static build, continue.
StaticHost will not run astro build for you. Upload dist/. No SPA fallback: try_files $uri $uri/ =404.
Static configuration
astro.config.mjs:
import { defineConfig } from 'astro/config'
export default defineConfig({
output: 'static', // default in many setups; be explicit if you ever toggled SSR
site: 'https://example.com',
base: '/',
build: {
format: 'directory', // or 'file' — know which you chose
},
})
site: canonical URL used for sitemaps/absolute URLs; update when the custom domain is final.base: keep'/'for root hosting.output: 'server'+ adapter: stop—wrong product.
Build and publish
npm ci
npm run build
ls dist
cd dist && zip -r ../astro-site.zip .
Confirm index.html at zip root. Deploy via zip or GitHub artifact branch. Nested archives: zip guide. Dist mindset: host a dist folder.
Islands and client JS
Astro’s partial hydration ships small amounts of framework JS for interactive islands. Those files are still static assets. They do not require Node on StaticHost. Ensure hydrated components do not expect server-only env at runtime; use PUBLIC_ prefixed env for client-visible values, baked at build:
PUBLIC_API_URL=https://api.example.com npm run build
Routing formats
With build.format: 'directory', /about/ maps to about/index.html—friendly to try_files $uri $uri/. With 'file', expect about.html. Pick one and keep internal links consistent.
Dynamic routes are evaluated at build time for static output. Paths not generated 404—correct for this host.
SSR checklist (so you do not self-sabotage)
You are in the wrong place if you need:
import node from '@astrojs/node'
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
})
Remove the adapter, set output: 'static', and rebuild for StaticHost—or host the Node server elsewhere.
Verify
HTTPS preview immediately after deploy. Test content pages, an island interaction, image paths, and RSS if present. Roll back via deploy history. DNS verify → certificate for custom domains.
Plans: Starter $9 (1 site, 2 GB), Pro $30 (3 sites, 10 GB, staging), Scale $65 (10 sites, 30 GB), Business $130 (30 sites, 100 GB, teams). Trial ~1 day. No forever-free, cPanel, email, built-in CDN, WordPress/PHP.
Content collections
Collections compile at build time into pages. Large media still count against storage quotas—photography-heavy Astro sites may need higher tiers (photography portfolio).
A realistic week shipping host an astro website
Monday starts with a broken relative CSS path that only appears once the files leave a designer’s laptop. You flatten the zip so index.html sits at the archive root, redeploy to StaticHost, and HTTPS preview finally matches local intent. nginx behaves like try_files $uri $uri/ =404 with no SPA index fallback.
Wednesday adds a custom domain. DNS is created exactly as the dashboard specifies; verification lags an hour; the certificate appears afterward. Someone asks whether email is included—you point them at a mail vendor and keep MX untouched. Plans: Starter $9 (1 site, 2 GB), Pro $30 (3 sites, 10 GB, staging), Scale $65 (10 sites, 30 GB), Business $130 (30 sites, 100 GB, teams).
Thursday an engineer enables history-mode routing for a “cleaner URL.” Refresh on a nested path 404s. You revert to hash routing for the week’s deadline and schedule prerender work properly instead of inventing an nginx rewrite StaticHost will not apply. There is a short trial (~1 day), not a forever-free tier; no cPanel, no email, no built-in CDN product.
Friday staging on Pro receives a build with staging API URLs baked via public env prefixes. Production stays on last week’s known-good deploy until Monday’s review. Rollback remains one click if marketing’s late copy drop breaks mobile layout. WordPress/PHP needs a different kind of host.
StaticHost serves prebuilt files via zip or GitHub and does not run npm, Hugo, or Jekyll remotely.
That week is what host an astro website looks like when the host stays boring and the team respects file truth.
Worked example: leave SSR, keep the content
You inherited an Astro app with @astrojs/node because someone wanted “future API routes.” Marketing only needs articles and a contact CTA. Convert deliberately:
- Remove the adapter import and
adapter:key fromastro.config.mjs. - Set
output: 'static'(andsiteto your eventual HTTPS origin when known). - Delete server endpoints under
src/pages/api/or move them to an external API host. - Replace any
Astro.cookies/ request-time personalization with client-side calls or build-time content. - Rebuild:
rm -rf dist
PUBLIC_FORM_ENDPOINT=https://forms.example.com/ab12 npm run build
find dist -name 'index.html' | head
cd dist && zip -r ../astro-static.zip .
- Deploy to StaticHost. Open HTTPS preview. Confirm article URLs exist as files (
about/index.htmlwhen using directory format). Hard-refresh a nested path—expect 200 only if Astro emitted that path. - Attach DNS later; certificate follows verification. Do not stall launch waiting on a custom domain if preview already proves the tree.
Failure table (Astro static on StaticHost)
| Symptom | Likely cause | Fix |
|---|---|---|
| Build demands an adapter | output: 'server' still set | Switch to static; remove adapter |
Assets under /docs/… 404 | base: '/docs' leftover | Set base: '/' for root hosting; rebuild |
| Island click does nothing | Client script 404 or wrong PUBLIC_ bake | Network tab; rebuild with env present |
| RSS absolute URLs wrong | Stale site value | Update site; rebuild; redeploy |
Nested dist/index.html in zip | Zipped parent folder | cd dist before zipping |
| Deep link 404 after client nav works | Path never emitted as HTML | Add/prerender the page or accept hash UX |
Remember: View Transitions and islands are still static assets. They do not unlock SPA index.html fallback. nginx stays try_files $uri $uri/ =404. Related reading: host a dist folder online, SPA guide.
Image and content collection discipline
Collections and astro:assets work at build time. Huge photography trees inflate storage against plan caps (2/10/30/100 GB). Compress before build; do not expect a built-in CDN product to erase weight. For image-heavy portfolios see photography portfolio. Roll back from deploy history if a media-heavy publish blows budgets or layout.
FAQ
Can I use @astrojs/vercel or Netlify adapters here?
No. Those target other runtimes. Static output only.
Does View Transitions require special hosting?
No, as long as assets are published. Still no SPA rewrite for missing files.
Where do server endpoints go?
They do not run on StaticHost. Call external APIs from the client or move SSR elsewhere.
How do I stage content?
Build with staging site/PUBLIC_* values; deploy to a staging site on Pro+.
Is Astro better than Hugo for this host?
Both work when they emit files. Choose based on your content workflow, not hosting mythology.