Complete Walkthrough: Deploying SvelteKit to Cloudflare Pages with Prisma and PostgreSQL
A step-by-step guide to deploying a SvelteKit application to Cloudflare Pages with Prisma ORM and PostgreSQL database, including setup, configuration, and troubleshooting.
Introduction
This comprehensive walkthrough will guide you through the entire process of building and deploying a SvelteKit application to Cloudflare Pages with Prisma ORM and PostgreSQL database. We'll cover everything from initial setup to production deployment.
Prerequisites
Before we begin, make sure you have the following installed:
- Node.js 18+ or Bun (recommended for faster development)
- Git for version control
- Cloudflare account (free tier works great)
- PostgreSQL database (local or cloud-hosted)
Step 1: Project Setup
Let's start by creating a new SvelteKit project:
# Create a new SvelteKit project
npm create svelte@latest my-blog
cd my-blog
# Install dependencies
npm install
# Or if using Bun
bun create svelte@latest my-blog
cd my-blog
bun install
Step 2: Install Prisma and Database Dependencies
Add Prisma and PostgreSQL dependencies to your project:
# Install Prisma
npm install prisma @prisma/client
npm install -D prisma
# Install Cloudflare adapter for SvelteKit
npm install -D @sveltejs/adapter-cloudflare
# Or with Bun
bun add prisma @prisma/client
bun add -D prisma @sveltejs/adapter-cloudflare
Step 3: Configure SvelteKit for Cloudflare Pages
Update your svelte.config.js
to use the Cloudflare adapter:
import adapter from '@sveltejs/adapter-cloudflare';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter()
},
preprocess: vitePreprocess()
};
export default config;
Step 4: Initialize Prisma
Set up Prisma with your database:
# Initialize Prisma
npx prisma init
# This creates:
# - prisma/schema.prisma (database schema)
# - .env (environment variables)
Step 5: Configure Database Schema
Update your prisma/schema.prisma
file:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
posts BlogPost[]
@@map("user")
}
model BlogPost {
id Int @id @default(autoincrement())
title String
slug String @unique
content String
excerpt String?
publishedAt DateTime? @default(now()) @map("published_at")
isPublished Boolean @default(false) @map("is_published")
authorId Int? @map("author_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
author User? @relation(fields: [authorId], references: [id])
@@map("blog_post")
}
Step 6: Set Up Environment Variables
Create a .env
file in your project root:
# Local development database
DATABASE_URL="postgresql://username:password@localhost:5432/your_database"
# For production, you'll use Prisma Accelerate URL
# DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=..."
Step 7: Create Database Client
Create src/lib/server/db/prisma.ts
:
import { PrismaClient } from "@prisma/client";
import { env } from "$env/dynamic/private";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
const createPrismaClient = () => {
const databaseUrl = env.DATABASE_URL;
if (!databaseUrl) {
throw new Error('DATABASE_URL environment variable is not set');
}
// Check if this is a Prisma Accelerate URL (for production)
const isAccelerateUrl = databaseUrl.startsWith('prisma://') || databaseUrl.startsWith('prisma+postgres://');
if (isAccelerateUrl) {
// Use Prisma Accelerate for production
const { PrismaClient: EdgePrismaClient } = require("@prisma/client/edge");
const { withAccelerate } = require("@prisma/extension-accelerate");
return new EdgePrismaClient({
datasourceUrl: databaseUrl,
}).$extends(withAccelerate());
} else {
// Use regular Prisma client for local development
process.env.DATABASE_URL = databaseUrl;
return new PrismaClient();
}
};
export const prisma = globalForPrisma.prisma ?? createPrismaClient();
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
Step 8: Generate Prisma Client
Generate the Prisma client for your schema:
# Generate Prisma client
npx prisma generate
# Create and apply database migrations
npx prisma migrate dev --name init
Step 9: Create Database Routes
Create a blog listing page at src/routes/blog/+page.server.ts
:
import { prisma } from '$lib/server/db/prisma';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async () => {
const posts = await prisma.blogPost.findMany({
where: {
isPublished: true
},
select: {
id: true,
title: true,
slug: true,
excerpt: true,
publishedAt: true,
content: true
},
orderBy: {
publishedAt: 'desc'
}
});
return {
posts
};
};
Step 10: Set Up Cloudflare Pages Configuration
Create a wrangler.toml
file in your project root:
name = "your-project-name"
compatibility_date = "2025-01-01"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = ".svelte-kit/cloudflare"
[env.production]
# Production environment variables will be set in Cloudflare dashboard
DATABASE_URL = "your-prisma-accelerate-url"
[env.preview]
# Preview environment variables
DATABASE_URL = "your-prisma-accelerate-url"
Step 11: Set Up Prisma Accelerate (Production Database)
For production, you'll need a PostgreSQL database that works with Cloudflare Workers:
- Sign up for Prisma Accelerate at cloud.prisma.io
- Create a new project and connect your PostgreSQL database
- Get your connection string that starts with
prisma+postgres://
- Set it as DATABASE_URL in your Cloudflare Pages environment variables
Step 12: Create Deployment Scripts
Add these scripts to your package.json
:
{
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev",
"db:migrate:deploy": "prisma migrate deploy",
"db:studio": "prisma studio",
"deploy": "npm run build && wrangler pages deploy .svelte-kit/cloudflare",
"deploy:with-migrations": "npm run db:migrate:deploy && npm run build && wrangler pages deploy .svelte-kit/cloudflare"
}
}
Step 13: Deploy to Cloudflare Pages
Deploy your application:
# Install Wrangler CLI
npm install -g wrangler
# Login to Cloudflare
wrangler login
# Deploy your application
npm run deploy:with-migrations
Step 14: Configure Environment Variables in Cloudflare
Set up your production environment variables:
- Go to your Cloudflare dashboard
- Navigate to Pages → Your Project → Settings → Environment variables
- Add
DATABASE_URL
with your Prisma Accelerate connection string - Set it for both Production and Preview environments
Step 15: Test Your Deployment
After deployment, test your application:
- Visit your Cloudflare Pages URL
- Test the blog functionality
- Check that database connections work
- Verify that server-side rendering works correctly
Common Issues and Solutions
Issue: "PrismaClient is not configured to run in Cloudflare Workers"
Solution: Use Prisma Accelerate and the edge client as shown in Step 7.
Issue: "DATABASE_URL environment variable is not set"
Solution: Make sure you've set the environment variable in Cloudflare Pages dashboard.
Issue: Build fails with Node.js compatibility errors
Solution: Add compatibility_flags = ["nodejs_compat"]
to your wrangler.toml
.
Performance Optimizations
To get the best performance:
- Use Prisma Accelerate for connection pooling and caching
- Enable edge rendering in SvelteKit
- Optimize images and static assets
- Use Cloudflare's CDN for global distribution
Monitoring and Debugging
Monitor your deployment:
# View deployment logs
wrangler pages deployment tail
# List deployments
wrangler pages deployment list
# View real-time logs
wrangler pages deployment tail [deployment-id]
Conclusion
You now have a fully functional SvelteKit application deployed to Cloudflare Pages with Prisma and PostgreSQL! This setup provides:
- Global distribution through Cloudflare's CDN
- Automatic deployments on every git push
- Edge computing for optimal performance
- Type-safe database access with Prisma
- Scalable database connections with Prisma Accelerate
This architecture is perfect for blogs, content management systems, and other data-driven applications that need global reach and excellent performance.