PreviewDrop for SvelteKit

Deploy previews for SvelteKit apps

Push a branch, get a live preview URL. PreviewDrop builds your SvelteKit app with adapter-node, runs it as a real Node server, and posts the link to the pull request in under 60 seconds.

TL;DR
Switch to @sveltejs/adapter-node, add the Dockerfile, push. PreviewDrop builds and runs node build behind a TLS-terminated subdomain. SSR, form actions, hooks and +server.ts endpoints all run in a real Node process.

Dockerfile

Drop this at the root of your repo. PreviewDrop picks it up on the next push and builds it into a container behind a TLS-terminated subdomain.

Dockerfile
FROM node:22-slim AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:22-slim WORKDIR /app ENV NODE_ENV=production HOST=0.0.0.0 COPY --from=build /app/build ./build COPY package*.json ./ RUN npm ci --omit=dev EXPOSE 3000 CMD ["node", "build"]

Environment variables

Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.

VariableExample valueNote
PORT3000adapter-node reads PORT automatically.
HOST0.0.0.0Makes the server reachable from the proxy.
PROTOCOL_HEADERx-forwarded-protoPair with HOST_HEADER=x-forwarded-host so SvelteKit derives the right origin — see gotcha.

Common gotchas

Use @sveltejs/adapter-node, not adapter-auto

A standalone Node server only exists with @sveltejs/adapter-node. The default adapter-auto can silently select a Vercel/Netlify adapter in CI and produce no build/index.js to run.

Set the origin so form actions don’t fail CSRF

SvelteKit blocks cross-origin POSTs. Because preview URLs are generated per branch, set PROTOCOL_HEADER=x-forwarded-proto and HOST_HEADER=x-forwarded-host so it derives the origin from the proxy headers — otherwise form actions return a 403 on the preview domain.

Install production deps in the runtime stage

adapter-node’s build/ still needs your runtime dependencies. The Dockerfile copies package.json and runs npm ci --omit=dev so the server can resolve them.

Bind to 0.0.0.0

Set HOST=0.0.0.0 (done in the Dockerfile). Without it the server can bind to localhost inside the container and the preview will 502.

Why not Vercel or Netlify?

SvelteKit ships first-class Vercel and Netlify adapters — PreviewDrop is for when you’d rather self-host the adapter-node server, want password-protected previews to share before merge, prefer flat per-workspace pricing, or run SvelteKit alongside a backend service that also needs branch previews. One Dockerfile, every branch, your infra.

Preview your SvelteKit app in 5 minutes

Connect a repo, push a branch, get a URL. No credit card, no trial clock.

Start free