API reference
v0.1.0 โ minimal surface. Three exports. That's the API.
svelteRenderer(component, options)
Returns a Hono MiddlewareHandler that responds with an HTML document containing the SSR'd Svelte component, followed by a hydration script that mounts the matching client bundle.
| Option | Type | Required | Notes |
|---|---|---|---|
hydrateAs | string | yes | Matches a key in the bundles map passed to attachSvelteRoutes. |
props | Record<string, unknown> | no | Same props used by SSR and hydration. JSON-serialized into the page. |
title | string | no | Sets <title>. |
head | string | no | Extra raw <head> HTML. |
bodyClass | string | no | Class on the <body>. |
cacheControl | string | false | no | Cache-Control for the HTML. Defaults to "public, max-age=0, must-revalidate" โ deploys are visible immediately. Pass "public, max-age=60, s-maxage=300" to let Cloudflare cache the HTML. Pass false to omit the header. See Caching. |
attachSvelteRoutes(app, options)
Registers GET /__svelte/:id.{hash}.{js,css} routes on the Hono app (legacy unhashed :id.{js,css} also accepted, with weaker caching). Call once per app instance. Idempotent.
| Option | Type | Notes |
|---|---|---|
bundles | Record<string, ClientBundle> | Keyed by hydrateAs. The build helper produces this. Each ClientBundle is { js, css, hash? }; when hash is set, URLs are content-addressed and served with cache-control: immutable. |
prefix | string | Defaults to "/__svelte". Override only on collision. |
buildHonoSvelte(options)
From svelte-hono/build. Three esbuild passes โ a shared Svelte runtime chunk, one per-component client chunk, and one server pass โ emitting a single bundled worker with all client bundles inlined as build-time string constants. Every bundle is content-hashed so deploys never collide with browser/edge caches.
| Option | Type | Notes |
|---|---|---|
workerEntry | string | Path to your Worker entry (TS or JS). |
outDir | string | Output dir. worker.bundled.mjs lands here. |
components | Record<string, string> | id โ path to .svelte file. id matches hydrateAs. |
target | string | Defaults "es2022". |
dev | boolean | Source maps + no minify. Defaults false. |
bundlesFile | string | Filename of the generated bundles module, relative to the worker entry's directory. Defaults to "bundles.generated.ts". |
skipWorkerBundle | boolean | Only build client bundles + write bundles.generated.ts; skip the final worker bundle. Useful when another tool (e.g. wrangler) bundles the worker. |
The generated bundles import
buildHonoSvelte() writes bundles.generated.ts next to your worker entry. Import it like any other module:
import { bundles } from "./bundles.generated";
attachSvelteRoutes(app, { bundles }); Add it to .gitignore โ it's regenerated each build. No globals, no declare const, no esbuild define magic to learn.
Mounting on a custom DOM node
The generated hydrate function accepts an optional second argument:
hydrate(props, target?) When omitted, it mounts on #svelte-hono-root (the default SSR target). Pass a different element to embed multiple components on one page โ for example, mounting Svelte islands into Hono JSX output.
Constraints
- Build-time compile. No
evalat runtime โ Workers prohibits it. See Why. - Default SSR root. Without a custom target, mount goes to
#svelte-hono-root. Pass a target tohydrate(props, target)for multi-component pages. - Non-streaming HTML. Full document in one Response. Workers fan out at the edge; streaming is rarely the right primitive at this size.
- Hono owns routing. No file-system router, no
loadfunctions, no+layout.svelte. Use Hono. That's the point.