
SvelteKit with adapter-static, my workflow for backend-free sites
No Node server in production and no database of its own. Here's how I build fully static sites with SvelteKit.
One of my first misconceptions about SvelteKit was thinking that, being a framework “with a server” by default, it forced me to keep one running in production even for projects that don’t need it at all. That’s not the case, and @sveltejs/adapter-static is the piece that proves it.
What it actually does
Instead of deploying a Node server that renders every page on request, adapter-static generates all the HTML, CSS and JS at build time — every route becomes a real .html file, ready to serve from any static file hosting, with no server infrastructure whatsoever. For a blog, a portfolio, or a client site that doesn’t need its own server logic, it’s exactly what’s needed: all the benefits of developing with a modern framework, without carrying the cost of keeping a server running twenty-four hours a day.
Dynamic routes are the part you need to understand well
What’s most confusing at first is how to prerender dynamic routes like /blog/[slug]. adapter-static can’t guess which slugs exist — you have to tell it explicitly with an entries() function in that route’s +page.ts, which returns the full list of slugs to generate. The first time I forgot to add it, the build failed with a pretty clear error, so it’s not a silent failure either — but you do need to know it exists.
The trick I forget most often, even to myself
During prerendering, anything that depends on the site’s real domain (page.url.origin, for example) returns a made-up host like http://sveltekit-prerender, because at that point there’s no real request yet. If you use that value to build an absolute URL — the canonical, the og:image, the sitemap — that fake host stays published as-is in the final HTML. The fix is to have a single function that centralises the real domain from the site’s config, and always use that instead of trusting the request URL.
Why I keep choosing this
Zero server to update, zero database to back up, zero attack surface beyond a file host. For the kind of projects I do — where content lives in the repository itself, not in a database — it’s the combination with the fewest things that can break while I sleep.