Deploy SvelteKit to thin.host
Prerender a SvelteKit app with adapter-static and publish the build/ folder to thin.host. thin.host serves the static files and gives you a live URL right away. Your agent can do every step for you through the thin.host MCP server, or you can run one curl command.
At a glance
| Step | SvelteKit |
|---|---|
| Build command | npm run build |
| Folder to deploy | build/ |
Preview build (served at /s/my-site/) | BASE_PATH=/s/my-site npm run build |
| Deploy | curl -F file=@site.zip -H "Authorization: Bearer $THINHOST_API_KEY" https://thin.host/v1/websites/archive |
| Live URL | https://thin.host/s/my-site/, or your own domain |
Before you start
- Requires: Node.js 22.17 or later for SvelteKit 3.
- A thin.host account. Sign up, then create an API key under Settings (for
curland the local MCP server), or connect your agent with OAuth as shown in Quickstart (MCP).
Create a project (skip if you have one)
npx sv create my-app
Make the build fully static
Install adapter-static, pass it to the sveltekit() Vite plugin, and prerender every page from the root layout. SvelteKit 3 (October 2026) reads this from vite.config.js; on SvelteKit 2 the same adapter and paths options go under kit in svelte.config.js.
// vite.config.js
// npm i -D @sveltejs/adapter-static
import { sveltekit } from '@sveltejs/kit/vite';
import adapter from '@sveltejs/adapter-static';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
sveltekit({
adapter: adapter(),
paths: { base: process.env.BASE_PATH ?? '' },
}),
],
});
// src/routes/+layout.js
export const prerender = true;
Set the base path
Until a domain points at it, a thin.host site lives under a sub-path: https://thin.host/s/<slug>/. The paths.base option must be empty or start with a slash, and must not end with one. Build links with resolve() from $app/paths so they follow it (SvelteKit 3 removed the base export).
<script>
import { resolve } from '$app/paths';
</script>
<a href={resolve('/about')}>About</a>
| Where readers will look | Build with |
|---|---|
The preview URL https://thin.host/s/my-site/ | BASE_PATH=/s/my-site npm run build |
A custom domain, or a free <name>.thin.host subdomain | npm run build (base path /) |
Pick the slug (my-site here) before you build the preview, and pass the same slug when you deploy.
Build
npm run build
The finished site is in build/. That folder is what you deploy.
Deploy from your agent (MCP)
Connect thin.host to Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, Codex or ChatGPT once (setup for each client), then ask:
Build this SvelteKit project for thin.host with the slug my-site and publish the build/ folder.
With the local server (uvx thinhost-mcp) the agent runs the build and calls publish_website with the absolute path of build/; large builds are split across requests automatically. Later changes go out with update_website and sync=true, which also removes files the new build dropped.
The hosted connector (https://thin.host/mcp, used by claude.ai and ChatGPT) cannot read your disk. From a coding agent it uploads with the REST call below; otherwise it publishes from a public link to a zip or HTML file with publish_website_from_url.
Deploy with curl
cd build && zip -r ../site.zip . && cd -
curl -F file=@site.zip -F title="My SvelteKit site" -F slug=my-site \
-H "Authorization: Bearer $THINHOST_API_KEY" \
https://thin.host/v1/websites/archive
The JSON response includes url, the live address (https://thin.host/s/my-site/). To redeploy, upload the new zip to the site's archive endpoint; pages and assets missing from it are removed:
curl -F file=@site.zip \
-H "Authorization: Bearer $THINHOST_API_KEY" \
https://thin.host/v1/websites/my-site/archive
A single upload can be up to 30 MB. See the REST API reference for every field.
Add a custom domain
- Open the site in the dashboard and add your hostname under Custom Domains, for example
www.example.com. A<name>.thin.hostsubdomain is free and works immediately. - Create the DNS record the dashboard shows: a
CNAMEpointing atcname.thin.host. TLS is issued automatically once DNS resolves. - Rebuild with the base path
/(npm run build) and redeploy.
Pages on a custom domain get a canonical tag, a generated robots.txt and a sitemap.xml.
SvelteKit notes
- Every route must be prerenderable. Dynamic routes no link reaches need entries (export const entries), or the build stops with "marked as prerenderable, but were not prerendered".
FAQ
Can I ship a client-side fallback page?
Yes. adapter({ fallback: '404.html' }) writes an SPA shell as 404.html, and thin.host serves 404.html for paths that are not files, so unprerendered routes render in the browser (with a 404 status). The SvelteKit docs warn that SPA mode costs performance and SEO, so prerender what you can.
Why does the preview URL load without styles or scripts?
The site is served under /s/<slug>/ until a custom domain points at it, so a build that references /assets/... asks the thin.host root for files that live under the sub-path. Build with the base path set to /s/<slug>/ for the preview, or map a domain (a free <name>.thin.host subdomain works) and build with base /.
How do I redeploy?
Rebuild, zip the output folder again and POST it to /v1/websites/<slug>/archive, or ask your agent to run update_website with sync=true. Sync removes files the new build no longer contains, so old hashed bundles do not pile up.
How large can a site be?
A single archive upload can be up to 30 MB. The local MCP server (uvx thinhost-mcp) reads the build folder directly and splits large sites across requests, up to 150 MB.
Sources
Commands and options checked against the official SvelteKit docs on 2026-10-14:
- SvelteKit: Static site generation (adapter-static)
- SvelteKit configuration: paths
- SvelteKit: Migrating to SvelteKit 3
Other frameworks: all deploy guides. Coming from another host? Compare thin.host.