DeployxaDocs Portal
CLI v1.0.4
Deploy SvelteKit App
Framework guide · SvelteKit

Deploy a SvelteKit app

SvelteKit needs an adapter that matches where it runs. Use @sveltejs/adapter-node to run SSR, form actions and +server.ts endpoints as a Node.js server, or adapter-static for a fully prerendered site.

Prerequisites

  • A SvelteKit 2 project (created with npx sv create) and a committed lockfile.
  • Node.js 20 compatible dependencies.

How Deployxa detects SvelteKit

A @sveltejs/kit dependency selects the Svelte / SvelteKit preset on Node.js 20.

SettingValue
Build commandnpm run build
Output directorybuild (adapter-node and adapter-static default)
Start commandnode build (adapter-node)
Port3000

Required config: adapter-node

New projects use adapter-auto, which cannot tell it is running on Deployxa. Switch to the Node adapter:

shell
$ npm i -D @sveltejs/adapter-node
js
// svelte.config.js
import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: vitePreprocess(),
  kit: { adapter: adapter({ out: 'build' }) },
};

export default config;

Add a start script so the default start command works:

json
{
  "scripts": {
    "build": "vite build",
    "start": "node build"
  }
}

The built server listens on HOST and PORT (defaults 0.0.0.0 and 3000). Behind the HTTPS proxy, set ORIGIN to the public URL so form actions pass SvelteKit's CSRF check, or set PROTOCOL_HEADER=x-forwarded-proto and HOST_HEADER=x-forwarded-host.

Fully static sites

With @sveltejs/adapter-static and export const prerender = true in the root +layout.ts, the build writes plain files to build/. Use output directory build and no start command. For an SPA, set adapter({ fallback: 'index.html' }).

Environment variables

KeyPurposeExample
ORIGINPublic URL of the app (CSRF and absolute URLs)https://app.example.com
PORTListen port3000
PUBLIC_API_URLBrowser-safe value; read via $env/dynamic/public or $env/static/publichttps://api.example.com
DATABASE_URLServer-only; read via $env/dynamic/privatepostgresql://…

$env/static/* is inlined at build time; $env/dynamic/* is read when the server runs, so prefer it for values you change in the dashboard without rebuilding.

Databases

In the wizard's Configure step, set Database to PostgreSQL. The connection string is injected into the app as DATABASE_URL, so nothing needs to be committed. Choose SQLite only for small apps: it lives on a persistent volume and has no server.

ts
// src/lib/server/db.ts
import { env } from '$env/dynamic/private';
import pg from 'pg';

export const pool = new pg.Pool({ connectionString: env.DATABASE_URL });

Deploy

From the dashboard

  1. 1
    Source

    Open Dashboard → Projects → New project (/dashboard/projects/new). Pick the GitHub repository and branch, or upload a .zip archive of the project.

  2. 2
    Configure

    Leave the framework preset on Auto-detect or choose Svelte / SvelteKit. Check the fields under advanced settings:

    • Build command: npm run build
    • Output directory: build
    • Root directory: ./, or the sub-folder that holds the app in a monorepo
  3. 3
    Environment

    Add your variables in the table, or paste a whole .env file into the Bulk / .env tab.

  4. 4
    Deploy

    Start the deploy and watch the build log. When the release passes its health check it is served over HTTPS on its Deployxa URL.

  5. 5
    Confirm the start command and port

    Open the project's Environment Canvas tab and select the web service. Set Start Command to node build. Set Internal Port to 3000 so it matches the port your app listens on. Save and redeploy if you changed anything.

From the CLI

shell
$ npm install -g @deployxa/cli
$ deployxa login
$ cd my-app
$ deployxa link            # pick an existing project, or skip: deploy creates one
$ deployxa env set ORIGIN "https://app.example.com"
$ deployxa deploy
$ deployxa logs --live     # stream build and runtime logs
$ deployxa open            # open the live URL

If the folder is not linked, deployxa deploy creates a project named after the folder and links it (the link is saved in .deployxa/config.json). Later runs deploy the linked project. deployxa status shows the latest deployment and deployxa rollback previous returns to the release before it.

Warning: deployxa deploy packages the folder exactly as it is on disk; it does not read .gitignore. Delete local node_modules, virtualenvs, build output and real .env files first, or deploy from a clean clone. Set secrets with deployxa env set instead of shipping them in the archive.

Custom domain

Go to Dashboard → Domains, choose Connect a domain you already own and pick this project. Deployxa then shows the DNS records to create at your DNS provider:

RecordUse it forValue
AAn apex domain such as example.com85.17.244.184 (DNS only on Cloudflare)
CNAMEA subdomain such as www or appcname.deployxa.com (DNS only on Cloudflare)
TXTOnly when a CDN or proxy (for example Cloudflare orange-cloud) hides the origin recordHost _deployxa-challenge.<your-domain>, value deployxa-verification=…

DNS changes can take several minutes to propagate; use Retry verification once they have. A Let's Encrypt certificate is issued after the domain verifies. From a linked folder you can do the same with the CLI:

shell
$ deployxa domains add app.example.com
$ deployxa dns             # Waiting → Verified → SSL Active
$ deployxa domains list

Common errors and fixes

SymptomFix
"Could not detect a supported production environment"You are still on adapter-auto; install and configure adapter-node.
Cross-site POST form submissions are forbiddenSet ORIGIN to the exact public URL (including https://), and update it when you add a custom domain.
Missing script: "start"Add "start": "node build" or set the start command.
Cannot find package at runtimeadapter-node bundles only part of your dependencies; keep runtime packages in dependencies.

Start with deployxa logs --live (or the deployment's log view in the dashboard): the build log shows dependency and compile failures, the runtime log shows crashes and bind errors. See also Troubleshooting.