Complete guide to deploying your SvelteKit frontend on Netlify. Includes form handling, edge functions, and branch deploys.

12 min read

Deploying SvelteKit to Netlify

Netlify is a powerful platform for deploying SvelteKit applications, offering features like form handling, edge functions, and branch-based deployments. This guide walks through the complete deployment process.

Why Netlify?

  • JAMstack pioneer: Optimized for modern frontend frameworks
  • Form handling: Built-in form submissions without backend code
  • Edge functions: Run code at the edge ( Deno runtime)
  • Branch deploys: Every branch gets its own URL
  • Split testing: A/B testing with traffic splitting
  • Large free tier: Generous limits for side projects

Prerequisites

  • Git repository with SvelteKit code
  • Netlify account (free tier available)
  • Node.js 20+ installed

Install Development Tools

We recommend using mise (version manager) and pnpm (package manager) instead of npm:

Install mise:

curl https://mise.run | sh
# Add to your shell (follow post-install instructions)
echo 'eval "$(mise activate)"' >> ~/.bashrc
# or for zsh
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc

Install Node.js via mise:

mise use -g nodejs@latest

Install pnpm:

curl -fsSL https://get.pnpm.io/install.sh | sh -

Why pnpm over npm?

  • Faster installs through content-addressable storage
  • Strict dependency isolation prevents phantom dependencies
  • Disk space efficient through hard-linking
  • More reliable lockfile format

Step 1: Prepare Your Project

Configure Adapter

Install the Netlify adapter:

cd frontend
pnpm install -D @sveltejs/adapter-netlify

Update svelte.config.js:

import adapter from '@sveltejs/adapter-netlify';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

const config = {
  preprocess: vitePreprocess(),
  kit: {
    adapter: adapter({
      // Optional: split routes into separate functions
      split: false
    })
  }
};

export default config;

Environment Variables

Create frontend/.env.production:

PUBLIC_API_URL=https://tcs-svc-9k2m.yourdomain.com
PUBLIC_GRAPHQL_ENDPOINT=https://tcs-svc-9k2m.yourdomain.com/graphql
PUBLIC_APP_URL=https://your-app.netlify.app

Security Note: Use an obscure subdomain like tcs-svc-9k2m instead of predictable names like api or backend. Attackers scan for common subdomains automatically. An unguessable name hides your backend from reconnaissance and reduces automated attacks.

Netlify Configuration

Create frontend/netlify.toml:

[build]
  command = "pnpm run build"
  publish = "build"

[build.environment]
  NODE_VERSION = "20"

[[redirects]]
  from = "/api/*"
  to = "https://tcs-svc-9k2m.yourdomain.com/api/:splat"
  status = 200
  force = true

[[redirects]]
  from = "/graphql"
  to = "https://tcs-svc-9k2m.yourdomain.com/graphql"
  status = 200
  force = true

[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-Content-Type-Options = "nosniff"
    Referrer-Policy = "strict-origin-when-cross-origin"

Step 2: Deploy via Web UI

Connect Repository

  1. Go to netlify.com and log in
  2. Click "Add new site" → "Import an existing project"
  3. Connect to Git provider (GitHub, GitLab, Bitbucket)
  4. Select your repository

Configure Build Settings

Netlify auto-detects SvelteKit, but verify:

  • Build command: pnpm run build
  • Publish directory: build
  • Production branch: main

If your frontend is in a subdirectory:

  • Base directory: frontend

Click "Deploy site"

Wait for Deployment

Netlify builds and deploys your site. You'll receive:

  • Site URL: https://random-name-123456.netlify.app
  • Admin URL: https://app.netlify.com/sites/your-site

Step 3: Deploy via CLI

Install Netlify CLI

pnpm add -g netlify-cli

Login

netlify login

Initialize Project

cd frontend
netlify init

Select:

  • "Create & configure a new site"
  • Your team
  • Site name (optional)

Deploy

Draft deploy (for testing):

netlify deploy

Production deploy:

netlify deploy --prod

Step 4: Environment Variables

Via Web UI

  1. Site settings → Environment variables
  2. Add variables:
    • Key: PUBLIC_API_URL
    • Value: https://tcs-svc-9k2m.yourdomain.com
    • Scope: All (or Production/Deploy previews)

Via CLI

netlify env:set PUBLIC_API_URL https://tcs-svc-9k2m.yourdomain.com

Via netlify.toml

[context.production.environment]
  PUBLIC_API_URL = "https://tcs-svc-9k2m.yourdomain.com"

[context.deploy-preview.environment]
  PUBLIC_API_URL = "https://tcs-stg-4m7k.yourdomain.com"

Step 5: Custom Domain

Add Domain

  1. Site settings → Domain management
  2. Click "Add custom domain"
  3. Enter your domain: yourapp.com
  4. Click "Verify"

Configure DNS

Option A: Netlify DNS (Recommended)

  1. Change nameservers at your registrar to:
    dns1.p04.nsone.net
    dns2.p04.nsone.net
    dns3.p04.nsone.net
    dns4.p04.nsone.net

Option B: External DNS (CNAME)

Add CNAME record:

Type: CNAME
Name: www
Value: your-site.netlify.app

For apex domain (yourapp.com), use A records:

Type: A
Name: @
Value: 75.2.60.5
Value: 99.83.231.61

Enable HTTPS

Netlify automatically provisions SSL certificates via Let's Encrypt. No manual setup needed.

Step 6: Form Handling (Optional)

Netlify can handle form submissions without a backend:

Add Form to SvelteKit

<!-- src/routes/contact/+page.svelte -->
<form name="contact" method="POST" data-netlify="true">
  <input type="hidden" name="form-name" value="contact" />

  <label>
    Name
    <input type="text" name="name" required />
  </label>

  <label>
    Email
    <input type="email" name="email" required />
  </label>

  <label>
    Message
    <textarea name="message" required></textarea>
  </label>

  <button type="submit">Send</button>
</form>

View Submissions

Submissions appear in:

  • Netlify dashboard → Forms
  • Can be exported as CSV
  • Can trigger webhooks

Step 7: Edge Functions (Optional)

Create frontend/netlify/edge-functions/hello.ts:

import type { Config, Context } from '@netlify/edge-functions';

export default async (request: Request, context: Context) => {
  return new Response(JSON.stringify({
    message: "Hello from the edge!",
    location: context.geo?.city
  }), {
    headers: { 'Content-Type': 'application/json' }
  });
};

export const config: Config = {
  path: "/api/hello"
};

Edge functions run at the edge, close to users.

Advanced Configuration

Redirects and Rewrites

# netlify.toml
[[redirects]]
  from = "/old-path"
  to = "/new-path"
  status = 301

[[redirects]]
  from = "/api/*"
  to = "https://backend.example.com/:splat"
  status = 200
  force = true
  headers = {X-From = "Netlify"}

Headers

[[headers]]
  for = "/*.js"
  [headers.values]
    Cache-Control = "public, max-age=31536000"

Branch Deploy Contexts

[context.production]
  command = "pnpm run build"

[context.staging]
  command = "pnpm run build:staging"

[context.deploy-preview]
  command = "pnpm run build:preview"

Troubleshooting

Build Failures

Check build logs in Netlify dashboard. Common issues:

Node version mismatch:

[build.environment]
  NODE_VERSION = "20"

Lock file issues:

# Regenerate lock file
rm pnpm-lock.yaml
pnpm install

404 on Client-Side Routes

Add to netlify.toml:

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Or use the SvelteKit Netlify adapter which handles this automatically.

Environment Variables Not Working

  • Check scope (Production vs Deploy previews)
  • Ensure variables start with PUBLIC_ for browser access
  • Trigger a new deploy after adding variables

Production Checklist

  • Site builds without errors
  • Environment variables configured
  • Custom domain added (if applicable)
  • HTTPS enabled
  • API endpoints connect to backend
  • Forms working (if using Netlify Forms)
  • Branch deploys tested
  • Analytics configured (optional)

Next Steps