Deploying a Studio app

A Studio-generated app is a normal SvelteKit app - the screens are +page.svelte files and the data endpoints are +server.ts routes. It deploys anywhere SvelteKit runs. This page is the production checklist.

Checklist

License key

The generated screens import @svgrid/enterprise, which shows an unlicensed watermark until a key is set. Set it once at app startup:

// src/routes/+layout.ts (or a startup module)
import { setLicenseKey } from '@svgrid/enterprise'
setLicenseKey(import.meta.env.VITE_SVPRO_KEY)

Use per-environment keys so revoking one stage does not affect another. Validation is fully local - no network call.

Environment variables

The generated +server.ts reads the connection string from process.env.DATABASE_URL. Set it in your host's environment (Vercel / Netlify / Fly / a container), not in the repo:

DATABASE_URL="postgres://user:pass@host:5432/app"

Adapters

The API routes are standard SvelteKit endpoints, so any adapter works - adapter-node, adapter-vercel, adapter-netlify, adapter-cloudflare (with a Workers-compatible database driver), etc. No Studio-specific configuration is required.

Host Adapter Notes
Node / container @sveltejs/adapter-node One module-level pool per process; DATABASE_URL in the environment.
Vercel @sveltejs/adapter-vercel Serverless: use a pooler URL (see below). Set DATABASE_URL in project env.
Netlify @sveltejs/adapter-netlify Same as Vercel - functions are short-lived, so pool small.
Cloudflare @sveltejs/adapter-cloudflare Needs a Workers-compatible driver (e.g. Postgres over HTTP / Hyperdrive); the classic pg socket driver will not run on Workers.

Install and point svelte.config.js at the adapter, set DATABASE_URL in the host's env, and deploy - there is nothing Studio-specific to configure:

npm i -D @sveltejs/adapter-vercel   # or -node / -netlify / -cloudflare

Connection pooling

Security

Protect the data route

The generated +server.ts exports a single POST handler and is public by default. createKitHandlers returns that handler as a value, so wrap it with your own auth check before re-exporting - the wrapper runs first and the data handler only runs for authorized callers:

// src/routes/api/customers/+server.ts
import { error, type RequestEvent } from '@sveltejs/kit'
import { createSqlDataSource, createKitHandlers } from '@svgrid/enterprise'
import { customersSchema } from '$lib/customers.schema'
import { execute } from '$lib/db' // your parameterized SQL client: (text, params) => rows

const source = createSqlDataSource({ schema: customersSchema, table: 'customers', execute })
const handlers = createKitHandlers({ schema: customersSchema, source })

export async function POST(event: RequestEvent) {
  const session = await event.locals.getSession?.() // your auth (Lucia, Auth.js, Supabase, ...)
  if (!session) throw error(401, 'Unauthorized')
  return handlers.POST(event)
}

For a whole app, do the check once in src/hooks.server.ts and gate every /api/* route there instead of per-file. If you also want per-user row scoping, enforce it in the data source (a WHERE user_id = ... in your SQL, or Supabase RLS), not just at the route.

Migrations & schema drift

After a database migration, re-run the generator to pull new columns in:

npx @svgrid/studio add customers --db postgres --url "$DATABASE_URL"

Only the svgrid:managed regions regenerate - your customizations survive. See Code generation.

See also