A minimal SvelteKit SSR sample for
Embr, using
@sveltejs/adapter-node so the app
runs as a long-lived Node server (not a static export, not serverless).
Exercises:
- Request-time SSR via
+page.server.tsloadwithprerender = false - Client-side hydration via a Svelte 5 runes
$statecounter - A dedicated
/api/healthroute (+server.ts) for Embr's health check
Companion samples:
npm install -g @coreai-microsoft/embr-cli
embr login
embr quickstart deploy <your-user>/embr-sample-sveltekitplatform: nodejs
autoDeploy: true
run:
port: 3000
startCommand: "npm start" # package.json → "node build/index.js"
healthCheck:
enabled: true
path: "/api/health" # must be a backend route, not a page
expectedStatusCode: 200platform: nodejs— Oryx auto-detects frompackage.jsonand picks a Node LTS. Do not setbuildCommand: an explicitbuildCommandbypasses Oryx's Node pipeline and breaksnpm install/npm run buildwiring on Embr today (see embr#670).run.startCommand: "npm start"— resolves tonode build/index.js, the server emitted byadapter-node. The adapter readsPORTfrom env, which Embr injects.run.port: 3000— matchesadapter-node's default and the Embr-exposed port.healthCheck.path: "/api/health"— a frontend+page.sveltewould always return 200 and hide crashes. Use a+server.tsroute handler.
curl https://<deployment>/twice — the timestamp + nonce on the homepage should change each request (proves SSR is hitting the server on every hit).curl https://<deployment>/api/health—{"status":"ok",…}with HTTP 200.- Open the site in a browser — the "clicked N times" button should increment (proves hydration is intact through Embr's reverse proxy).
npm install
npm run devnpm install
npm run build # → ./build (adapter-node output)
npm start # → node build/index.js, listens on $PORT (default 3000)- Use
adapter-node, notadapter-auto.adapter-autoprobes for Vercel/Netlify/Cloudflare at install time and falls back to a warning build on Embr — you'll ship a container that can'tnpm start. - Don't set
buildCommandinembr.yaml. Let Oryx runnpm ci && npm run builditself frompackage.json. SettingbuildCommandexplicitly today bypasses the Node pipeline. - Don't
prerenderthe SSR route. SvelteKit will happily prerender a page whoseloadhas no dynamic input; if you want to prove SSR, setexport const prerender = falseon+page.server.ts(this sample does).