--static <dir> on a deploy publishes a
built frontend there after the backend import, and xanosdk publish republishes one without
touching the backend.
Publish with a deploy
Point--static at a directory your build already wrote:
npm run xano:deploy:ephemeral in a scaffolded project runs the second line for you.
The deploy reports the frontend’s URL as static.url:
Before archiving, the deploy writes the backend’s URL into every HTML document in the build as
window.XANO_HOST, so the same build works on any backend with no rebuild. Read it at runtime with
a build-time fallback:
--static-env KEY=VALUE (repeatable) adds more public config as window.<KEY>. Everything
injected is served to the browser, so never put a secret there. Typed frontend
covers calling your APIs from the app.
A deploy with --static does not write .env.local: the frontend reads its backend URL at
runtime.
Republish the frontend alone
xanosdk publish <dir> uploads a built directory and nothing else: no compile and no backend
import. With no --to, it publishes to the backend this project last deployed to.
--to also takes ephemeral:<name>, local:<name>, workspace and tenant:<name>. Publishing to
a workspace or a tenant asks before it replaces what its users see (--yes in CI). Publishing to
the Engine includes a SvelteKit app’s server half (below).
How long a frontend URL lasts
A deploy that replaces the backend also clears its static hosting. A deploy without--keep-data takes the published frontend down, and with --static publishes it again, possibly
at a new URL. The backend URL stays the same across the refresh.
To keep the frontend serving through a backend change, merge instead:
Routing and size limits
The deploy infers whether the build is a single-page app or one document per route.--static-routing spa|multipage overrides that, and is rarely needed.
Both are checked before anything is uploaded, so an oversize build stops the run with nothing
written. An upload that fails after the backend landed leaves the backend in place, exits
3,
and prints the xanosdk publish command that retries only the frontend.
Server rendering with SvelteKit on the Engine
On the Xano Engine, a SvelteKit app can render on the server. Build it with the SDK’s adapter, which needsesbuild in the app:
sveltekit() in
vite.config.ts, and it already uses this adapter:
frontend/src/routes/+layout.ts. Stop prerendering the
routes that should render per request. vite build then writes the client assets and prerendered
pages, a 404.html fallback shell, and the server half in .xano-ssr/. Deploy it to the Engine:
__data.json, a
form action) through the server half. A server load reads the Engine’s URL as XANO_HOST:
- It can hold secrets. SvelteKit inlines
$env/static/privatevalues into it, which is why the Engine never serves/.xano-ssr/. - It runs inside the Engine, not in Node. Keep state in your API, since module state is per
runtime. Bodies are buffered (no streaming),
request.formData()reads urlencoded forms only, and there is noAsyncLocalStorage. A render has 30 seconds and may answer up to 10 MB. - Other hosts serve only the static half. An ephemeral, a tenant or your workspace answers
every non-file path with the
404.htmlshell, which boots the app in the browser. Prerendered routes and routes with a universalloadwork there; a route whose data comes from+page.server.jsdoes not.
Next
- The backend your frontend calls: The Xano Engine or Ephemerals.
- Putting a frontend in front of a release: Promote and go live.