SvelteKit
adapter-static is required — adapter-auto produces a server build. Output lands in build/.
read as markdownSvelteKit ships with adapter-auto, which picks a server target based on
where it thinks it is being deployed. That produces a build Pages cannot serve.
Swap it for adapter-static.
$ npm i -D @sveltejs/adapter-static// svelte.config.js
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter(),
},
};
$ npm run buildvite v7.0.0 building SSR bundle for production...✓ Wrote site to "build"$ one9x pages release ./build --site mysite --deploy✓ v1 live→ https://mysite.one9x.app/Prerendered, or SPA?
This is the one decision, and it changes whether you pass --spa.
Prerendered (the default with adapter-static). Add both of these to
src/routes/+layout.js:
export const prerender = true;
export const trailingSlash = 'always';
prerender is what makes the adapter write anything at all. trailingSlash is
required, not a preference: without it the adapter writes build/about.html,
and Pages serves paths rather than routes — so a request for /about 404s. With
it, every route becomes build/about/index.html and resolves. The symptom if you
skip it is a homepage that works and internal links that all 404.
Do not pass --spa — a genuine 404 should be a 404.
SPA fallback. For an app whose routes can’t be prerendered (anything behind a login, anything keyed on runtime data), give the adapter a fallback page:
adapter({ fallback: 'index.html' })
Then deploy with --spa, so unmatched paths serve that fallback:
$ one9x pages release ./build --site myapp --spa --deploy✓ v1 live · unknown routes → /index.htmlYou can mix the two — prerender the marketing routes, fall back for the app —
but if any route relies on the fallback, you need --spa.
Server endpoints
+page.server.js, +server.js and form actions need a running server. With
adapter-static the build fails naming the route, which is the right outcome:
it tells you at build time rather than at 3am.
Start from a template
Live, and deployed by the workflow in that repo on every push: sveltekit.one9x.app.
one9x/template-sveltekit is a minimal SvelteKit starter
with this deploy already wired up. Press Use this template on GitHub to get
your own copy, or read it as a reference for a project you already have.
Set two things in the new repo under Settings → Secrets and variables → Actions and it deploys on every push:
| Name | Value | |
|---|---|---|
| Variable | ONE9X_SITE | the site to deploy to |
| Secret | ONE9X_TOKEN | one9x tokens create "github actions" |
Until ONE9X_SITE is set the workflow is skipped rather than failed — a fresh
copy should not open with a red X.
Deploying on every push
- uses: actions/setup-node@v5
with: { node-version: 22, cache: npm }
- run: npm ci
- run: npm run build
- uses: one9x/pages-deploy@v1
with:
site: mysite
dir: build
token: ${{ secrets.ONE9X_TOKEN }}
deploy: ${{ github.ref == 'refs/heads/main' }}
Add spa: true if you are using the fallback.