Skip to content

SvelteKit

Source: src/Cloudflare/Website/SvelteKit.ts

A Cloudflare Worker deployed from a SvelteKit project.

SvelteKit builds the app with SvelteKit’s own Vite pipeline and a wrangler-free in-memory Cloudflare adapter, then re-bundles the Node-flavored server output for workerd. A project-owned vite.config.* loads natively (its sveltekit(...) options apply) — no svelte.config.js (kit v3 dropped it), no @sveltejs/adapter-cloudflare, no Wrangler configuration required. Client assets and prerendered pages are deployed as Worker static assets; dynamic routes are served by the generated Worker.

The @alchemy.run/frontend-frameworks package must be installed in your project — its /sveltekit export is loaded dynamically at deploy time.

Input files are content-hashed (respecting .gitignore by default) so unchanged projects skip the build and deploy entirely.

SvelteKit’s server code runs under nodejs_compat (the server graph is built for Node), so the flag is always included in the Worker’s compatibility flags.

Note on local dev: alchemy dev runs SvelteKit’s own Vite dev server (Node SSR with full HMR). platform.env carries the Worker’s real Cloudflare bindings (KV, R2, D1, …) served by the cloudflare-runtime platform proxy, with literal env values (strings and secrets) overlaid.

A single call builds and deploys the app — server-rendered routes, prerendered pages, and client assets included.

const site = yield* Cloudflare.Website.SvelteKit("Website");

Values passed via env are exposed to server routes through SvelteKit’s platform.env.

const site = yield* Cloudflare.Website.SvelteKit("Website", {
env: {
API_KEY: Config.redacted("API_KEY"),
},
});
// src/routes/+page.server.ts
// export const load = ({ platform }) => ({
// hasKey: platform?.env?.API_KEY !== undefined,
// });

Kit options live in the sveltekit(...) call in your vite.config.ts, which loads natively. Fallback-page behavior is driven by the platform-native assets.notFoundHandling knob — the build generates the matching fallback page (rendering the app shell, so kit’s own error page shows).

App-shell 404 fallback

const site = yield* Cloudflare.Website.SvelteKit("Website", {
assets: {
notFoundHandling: "404-page",
},
});

The kit prop is a deploy-time override bag merged over your own sveltekit(...) options (the prop wins) — useful for per-stage values the config file can’t compute. JSON-serializable values only.

Deploy-time kit overrides

const site = yield* Cloudflare.Website.SvelteKit("Website", {
kit: {
paths: { base: "/docs" },
},
});

By default, every non-gitignored file is hashed to decide whether a rebuild is needed. Use memo to narrow the scope when the project lives in a large repository.

const site = yield* Cloudflare.Website.SvelteKit("Website", {
memo: {
include: ["src/**", "static/**", "package.json"],
},
});

Calling SvelteKit with no arguments returns a constructor you can extend to declare the Worker as a named class. The class is both an Effect you can yield* to deploy and a type you can reference elsewhere — useful when other resources need to bind to this Worker.

class Website extends Cloudflare.Website.SvelteKit<Website>()(
"Website",
) {}
const site = yield* Website;