This guide covers deploying nuxt-crouton applications to production environments.
nuxt-crouton apps are built on Nuxt and can deploy to any platform that supports Nuxt:
| Platform | Database | Recommended For |
|---|---|---|
| Cloudflare Pages | D1 (SQLite) | Production apps (recommended) |
| Vercel | Turso/PlanetScale | Vercel-native workflows |
| Netlify | Turso/PlanetScale | Netlify-native workflows |
| Self-hosted | Any SQLite/PostgreSQL | Full control |
npm install -g wrangler
wrangler login
# Create the database
wrangler d1 create my-app-db
# Output will include database_id - save this!
# ✅ Successfully created DB 'my-app-db'
# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Create KV for sessions/cache
wrangler kv:namespace create KV
# Output will include the id - save this!
# ✅ Successfully created KV namespace "KV"
# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Create or update wrangler.toml in your app directory:
name = "my-app"
compatibility_date = "2024-09-02"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = "dist"
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "your-database-id-here"
[[kv_namespaces]]
binding = "KV"
id = "your-kv-id-here"
Ensure your nuxt.config.ts is configured for Cloudflare:
export default defineNuxtConfig({
// ... your extends
// CRITICAL: Use db: 'sqlite', NOT database: true
hub: {
db: 'sqlite',
kv: true
},
// Disable incompatible features
croutonAuth: {
passkeys: false // Not supported on Cloudflare Workers
}
})
hub: { database: true } will cause build failures. Always use hub: { db: 'sqlite' }.| Variable | Description | Example |
|---|---|---|
BETTER_AUTH_SECRET | Session encryption (32+ chars) | Generate with openssl rand -base64 32 |
BETTER_AUTH_URL | Production URL | https://my-app.pages.dev |
# Generate a secure secret
openssl rand -base64 32
# Add to Cloudflare
npx wrangler pages secret put BETTER_AUTH_SECRET
# Paste the generated secret when prompted
npx wrangler pages secret put BETTER_AUTH_URL
# Enter your production URL
# Generate migrations (if not already done)
pnpm run db:generate
# Apply to production D1
pnpm run db:migrate:prod
# or: npx wrangler d1 migrations apply my-app-db --remote
# Build and deploy to production
pnpm run cf:deploy
# or: nuxt build && npx wrangler pages deploy dist
For preview deployments:
pnpm run cf:preview
# or: nuxt build && npx wrangler pages deploy dist --branch preview
https://your-domain.com/api/auth/callback/googlenpx wrangler pages secret put GOOGLE_CLIENT_ID
npx wrangler pages secret put GOOGLE_CLIENT_SECRET
https://your-domain.com/api/auth/callback/githubnpx wrangler pages secret put GITHUB_CLIENT_ID
npx wrangler pages secret put GITHUB_CLIENT_SECRET
Some features are disabled or limited on Cloudflare Workers:
| Feature | Status | Reason | Workaround |
|---|---|---|---|
| Passkeys/WebAuthn | Disabled | tsyringe incompatible | Use email/password or OAuth |
| OG Image Generation | Optional | Reduces bundle (~4MB) | Use static OG images |
| Long-running tasks | Limited | 30s CPU limit | Use Cloudflare Queues |
Configuration for disabled features:
// nuxt.config.ts
export default defineNuxtConfig({
croutonAuth: {
passkeys: false
}
})
wrangler loginwrangler d1 create {app}-dbwrangler kv:namespace create KVwrangler.toml with database_id and KV idBETTER_AUTH_SECRET (32+ character secret)BETTER_AUTH_URL (your production URL)pnpm run db:migrate:prodpnpm run cf:deploypnpm run db:generatepnpm run db:migrate:prodpnpm run cf:deployCause: Environment variable not set in Cloudflare.
Fix:
openssl rand -base64 32 # Generate secret
npx wrangler pages secret put BETTER_AUTH_SECRET
# Paste the generated secret
Then redeploy.
Cause: Using hub: { database: true } instead of hub: { db: 'sqlite' }.
Fix: Update nuxt.config.ts:
hub: {
db: 'sqlite', // NOT database: true
kv: true
}
Cause: Database not created or wrong database_id.
Fix:
wrangler d1 listwrangler.toml has correct database_idwrangler d1 migrations apply {app}-db --remoteCause: Callback URL mismatch or missing BETTER_AUTH_URL.
Fix:
BETTER_AUTH_URL is set to your production URLhttps://your-domain.com/api/auth/callback/googlehttps://your-domain.com/api/auth/callback/githubCause: Passkey dependencies are incompatible with Workers.
Fix: Disable passkeys in config:
croutonAuth: {
passkeys: false
}
# Wrangler Management
wrangler login # Authenticate
wrangler d1 list # List databases
wrangler kv:namespace list # List KV namespaces
wrangler pages secret list # List secrets
wrangler pages secret put X # Add secret X
wrangler tail # View live logs
# Database Operations
pnpm run db:generate # Generate migrations
pnpm run db:migrate # Apply locally
pnpm run db:migrate:prod # Apply to production
# Deployment
pnpm run cf:deploy # Deploy production
pnpm run cf:preview # Deploy preview
nuxt.config.ts:export default defineNuxtConfig({
nitro: {
preset: 'vercel'
}
})
nuxt build
node .output/server/index.mjs