Deploy SvelteKit
deploybase supports SvelteKit with adapter-static, in two shapes: a fully prerendered static site, or a single-page app that routes in the browser. Server-side rendering and form actions that require a Node.js runtime are not supported.
Requirements
Section titled “Requirements”- SvelteKit 2+
@sveltejs/adapter-staticinstalled
Configuration
Section titled “Configuration”Install adapter-static
Section titled “Install adapter-static”npm install -D @sveltejs/adapter-staticPick your path
Section titled “Pick your path”| What you are building | Use |
|---|---|
| Marketing site, docs, blog, portfolio | Prerendered static site |
| App with client-side routing or dynamic routes you cannot list at build time | Single-page app |
Both paths use adapter-static and both deploy the same way. Only svelte.config.js and your root layout differ.
Prerendered static site
Section titled “Prerendered static site”Every route is written to its own HTML file at build time, so each URL is served as real HTML. This is the better choice for content sites: search engines and social previews get a full page without running JavaScript.
svelte.config.js:
import adapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */const config = { kit: { adapter: adapter({ pages: 'build', assets: 'build', fallback: undefined, precompress: false, strict: true, }), },};
export default config;src/routes/+layout.js:
export const prerender = true;Every route has to be prerenderable. For dynamic routes that SvelteKit cannot find by crawling links, export an entries function from the corresponding +page.js.
Single-page app
Section titled “Single-page app”SPA mode emits one app shell, 200.html, and lets the SvelteKit router resolve URLs in the browser. Use it when routes depend on data that only exists at runtime, such as a dashboard behind a login.
svelte.config.js:
import adapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */const config = { kit: { adapter: adapter({ pages: 'build', assets: 'build', fallback: '200.html', precompress: false, strict: false, }), },};
export default config;src/routes/+layout.js:
export const ssr = false;You do not need export const prerender = true in SPA mode, and you do not need to enumerate dynamic routes.
The fallback: '200.html' above is the only thing you need: deploybase picks that file up on its own and serves it for any path with no matching file, so deep links and hard reloads land in your app. See SPA fallback and custom 404 pages for the full detection rules and the _redirects alternative.
Mixing prerendering and SPA mode is fine: routes you mark prerender = true are still written as their own HTML files, and the fallback only covers what is left over.
deploybase Defaults
Section titled “deploybase Defaults”| Setting | Value |
|---|---|
| Framework | sveltekit |
| Build command | npm run build |
| Output directory | build |
| Docker image | node:24-alpine |
Create and Deploy
Section titled “Create and Deploy”curl -X POST https://api.deploybase.eu/api/v1/projects \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "My SvelteKit Site", "framework": "sveltekit", "git_repo_url": "https://github.com/user/sveltekit-site.git", "git_provider": "github" }'Common Issues
Section titled “Common Issues”Build fails with “adapter-static requires prerender”: adapter-static needs to know what to write to disk, and one of your routes cannot be prerendered. There are two ways forward.
- Prerender everything. Add
export const prerender = true;tosrc/routes/+layout.jsand exportentriesfor any dynamic route SvelteKit cannot reach by crawling. Best for content sites. - Switch to SPA mode. Set
fallback: '200.html'in the adapter options andexport const ssr = false;in your root+layout.js. Routes resolve in the browser, and deploybase serves200.htmlfor paths with no matching file.
Setting strict: false on its own also silences the build error, but any route left unrendered has no file behind it. Without a 200.html (or a _redirects catch-all) in the build output, those URLs fall through to your 404 page.
Deep links 404 in a SPA: check that build/200.html exists in the build output. If your adapter config sets fallback to something else, such as index.html, rename it to 200.html or add a _redirects file with /* /index.html 200.
Using bun instead of npm: bun is supported natively. If your repository has a bun.lock or bun.lockb committed, deploybase detects it and installs with bun automatically. To set it explicitly:
curl -X PATCH https://api.deploybase.eu/api/v1/projects/PROJECT_ID \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"package_manager": "bun"}'The build command stays npm run build, which runs the build script from your package.json against the dependencies bun installed. See Build System for the full package-manager reference.