Complete guide to deploying your SvelteKit frontend on Cloudflare Pages. Includes edge functions, global CDN, and privacy-focused deployment.

12 min read

Deploying SvelteKit to Cloudflare Pages

Cloudflare Pages is a powerful, privacy-focused platform for deploying SvelteKit applications. With a global CDN, edge functions, and generous free tier, it's an excellent choice for hosting your frontend.

Why Cloudflare Pages?

  • Privacy-first: Cloudflare does not use your data for AI training
  • Global CDN: 300+ locations worldwide for fast load times
  • Edge functions: Run code at the edge (Cloudflare Workers runtime)
  • Generous free tier: Unlimited bandwidth, 500 builds/month
  • Git integration: Automatic deployments from GitHub/GitLab
  • Custom domains: Free SSL with automatic renewal

Prerequisites

  • Git repository with SvelteKit code
  • Cloudflare 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 Cloudflare adapter:

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

Update svelte.config.js:

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

const config = {
  preprocess: vitePreprocess(),
  kit: {
    adapter: adapter({
      // Optional: configure routes
      routes: {
        include: ['/*'],
        exclude: ['<all>']
      }
    })
  }
};

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.pages.dev

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.

Step 2: Deploy via Web UI

Connect Repository

  1. Go to dash.cloudflare.com and log in
  2. Navigate to "Pages" in the left sidebar
  3. Click "Create a project"
  4. Connect to Git provider (GitHub or GitLab)
  5. Select your repository

Configure Build Settings

Cloudflare auto-detects SvelteKit, but verify:

  • Framework preset: SvelteKit
  • Build command: pnpm run build
  • Build output directory: .svelte-kit/cloudflare
  • Production branch: main

If your frontend is in a subdirectory:

  • Root directory: frontend

Click "Save and Deploy"

Wait for Deployment

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

  • Site URL: https://your-app.pages.dev
  • Dashboard URL: https://dash.cloudflare.com/[account]/pages/view/your-app

Step 3: Environment Variables

Via Web UI

  1. Go to your Pages project → Settings → Environment variables
  2. Add variables:
    • Key: PUBLIC_API_URL
    • Value: https://tcs-svc-9k2m.yourdomain.com
    • Environment: Production (and Preview if needed)

Via Wrangler CLI

First, install Wrangler:

pnpm add -g wrangler

Login to Cloudflare:

wrangler login

Set environment variables:

wrangler pages project env add PUBLIC_API_URL
# Enter value when prompted

Step 4: Custom Domain

Add Domain

  1. Go to your Pages project → Custom domains
  2. Click "Set up a custom domain"
  3. Enter your domain: yourapp.com
  4. Click "Continue"

Configure DNS

Cloudflare will prompt you to either:

Option A: Use Cloudflare as DNS provider (Recommended)

  1. Change nameservers at your registrar to Cloudflare's nameservers (provided in setup)
  2. Cloudflare automatically handles SSL and routing

Option B: Use external DNS

Add a CNAME record:

Type: CNAME
Name: www
Value: your-app.pages.dev

For apex domain (yourapp.com), use:

Type: A
Name: @
Value: 192.0.2.1

Enable HTTPS

Cloudflare automatically provisions SSL certificates. No manual setup needed.

Step 5: Edge Functions (Optional)

Cloudflare Pages supports edge functions through Cloudflare Workers:

Create frontend/functions/api/hello.ts:

export interface Env {}

export const onRequest: PagesFunction<Env> = async (context) => {
  const { request, env } = context;

  return new Response(JSON.stringify({
    message: "Hello from the edge!",
    timestamp: new Date().toISOString()
  }), {
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'public, max-age=60'
    }
  });
};

Edge functions run at Cloudflare's edge locations, close to users.

Advanced Configuration

_headers File

Create frontend/static/_headers for custom headers:

/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin

/*.js
  Cache-Control: public, max-age=31536000, immutable

_redirects File

Create frontend/static/_redirects for redirects:

/old-path /new-path 301
/api/* https://tcs-svc-9k2m.yourdomain.com/api/:splat 200

wrangler.toml Configuration

Create frontend/wrangler.toml for advanced settings:

name = "your-app"
compatibility_date = "2024-01-01"

[env.production]
vars = { ENVIRONMENT = "production" }

[env.staging]
vars = { ENVIRONMENT = "staging" }

Troubleshooting

Build Failures

Check build logs in Cloudflare dashboard. Common issues:

Node version mismatch: Add to package.json:

{
  "engines": {
    "node": "20"
  }
}

Lock file issues:

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

404 on Client-Side Routes

The Cloudflare adapter handles this automatically. If issues persist, check:

  • svelte.config.js uses @sveltejs/adapter-cloudflare
  • Build output directory is .svelte-kit/cloudflare

Environment Variables Not Working

  • Check environment (Production vs Preview)
  • Ensure variables start with PUBLIC_ for browser access
  • Trigger a new deploy after adding variables
  • For private variables (server-side only), don't use PUBLIC_ prefix

API Routes Not Working

Verify in svelte.config.js:

adapter: adapter({
  routes: {
    include: ['/*'],
    exclude: ['<all>']
  }
})

Production Checklist

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

Next Steps