Complete guide to deploying your SvelteKit frontend on Netlify. Includes form handling, edge functions, and branch deploys.
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)"' >> ~/.zshrcInstall Node.js via mise:
mise use -g nodejs@latestInstall 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-netlifyUpdate 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.appSecurity 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
- Go to netlify.com and log in
- Click "Add new site" → "Import an existing project"
- Connect to Git provider (GitHub, GitLab, Bitbucket)
- 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-cliLogin
netlify loginInitialize Project
cd frontend
netlify initSelect:
- "Create & configure a new site"
- Your team
- Site name (optional)
Deploy
Draft deploy (for testing):
netlify deployProduction deploy:
netlify deploy --prodStep 4: Environment Variables
Via Web UI
- Site settings → Environment variables
- Add variables:
- Key:
PUBLIC_API_URL - Value:
https://tcs-svc-9k2m.yourdomain.com - Scope: All (or Production/Deploy previews)
- Key:
Via CLI
netlify env:set PUBLIC_API_URL https://tcs-svc-9k2m.yourdomain.comVia 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
- Site settings → Domain management
- Click "Add custom domain"
- Enter your domain:
yourapp.com - Click "Verify"
Configure DNS
Option A: Netlify DNS (Recommended)
- 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.appFor apex domain (yourapp.com), use A records:
Type: A
Name: @
Value: 75.2.60.5
Value: 99.83.231.61Enable 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 install404 on Client-Side Routes
Add to netlify.toml:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Or 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)