Static
On the static adapter, the build produces files and the runtime executes nothing. Every request is answered from those files, cached at the points of presence and served from the one nearest the reader — so a cache hit never reaches the origin at all.
That makes it the fastest and cheapest thing to run, and the reason to reach for it around a storefront rather than for one: a landing page, a campaign microsite, documentation, a brochure site. A commerce storefront belongs on ssr, because prices, stock, carts and account pages are buyer-specific.
What you give up
Both of these are easy to forget until they bite:
- Environment variables are baked in at build time. There is no run time to read them at, so changing one always means a new deployment. See Build time versus run time.
- You cannot see your own logs. With no server, anything you log goes to your visitor's browser console. The site's logs show the request, not your output.
A credential is the case where this matters most. A value baked into a static bundle is public — it ships to every browser. If your static site needs to call the platform, it calls a public endpoint with a public key, or it doesn't call it.
Getting a site onto the static adapter
Normally you don't set it: the platform detects the adapter from what your build produced and remembers it on the site — see Frameworks.
Set it explicitly when detection is wrong:
revenexx sites update --site-id <SITE_ID> --adapter static
Or in Cockpit, under Experience Studio → Sites, in the site's build settings. Either way it applies from the next deployment, so create one afterwards.
Per-framework configuration
All fifteen supported frameworks can build static. Several need their static output configured in your own project first:
| Framework | What to configure |
|---|---|
| React · Vue · Vite · Lynx · React Native | Nothing. These are static-only. |
| Nuxt | Set the build command to npm run generate, not npm run build. |
| Next.js | Set output: 'export' in next.config.js. |
| SvelteKit | Use @sveltejs/adapter-static in svelte.config.js. |
| Astro | Leave adapter unset in astro.config.mjs. |
| Remix | Set ssr: false on the remix plugin in vite.config.ts. |
| Analog | Set static: true on the analog plugin in vite.config.ts. |
| TanStack Start | Add the prerender option with enabled: true to the tanstackStart config in vite.config.ts. |
| Angular | The default build emits a browser bundle; point the output directory at it. |
| Flutter | Nothing. flutter build web produces static output. |
The install command, build command and output directory that go with each are in Build configuration. Two catch people out: Nuxt's static build uses npm run generate, and Next.js changes its output directory entirely between adapters.
Single-page apps need a fallback file
A single-page app serves one HTML document and routes client-side. The URL changes without a request, which is fine until someone reloads on /products/42 or shares the link — now there is a request, for a path that has no file behind it, and the answer is a 404.
The fallback file fixes it. Set it in the site's build settings, usually to index.html: any request that doesn't match a file is served that document instead, and your client-side router takes over from there.
Set it when you create or update the site, alongside the adapter:
revenexx sites update --site-id <SITE_ID> --adapter static --fallback-file index.html
npm run dev and 404 in production, this is why.A prerendered site does not need it. If your build emitted a real file per route, every URL has something behind it already.
Debugging
- Deep links 404 but the home page works. Set the fallback file.
- The build succeeded but nothing is served. The output directory doesn't match what your build wrote. Check it against the per-framework defaults.
- A changed environment variable had no effect. It's baked in at build time. Create a new deployment.
- A stale asset keeps being served. The edge cache holds an entry for an hour and there is no purge API. Publish under a new path — a new URL is a new cache key. See Caching.
- My server-side code isn't running. Nothing executes per request on this adapter. Move to
ssr.
Related
- Server-side rendering — the other adapter, and what a storefront needs
- Rendering — the two adapters side by side
- Content delivery — how static output reaches the reader
- Environment variables — and why a static site always needs a rebuild
- Framework quick-starts — deploying a non-storefront app end to end