All Kit configuration happens through a single
apps/boilerplate/.env.local file and a branding config file. This page covers the essential settings you need to know. For a complete reference of every environment variable, see Environment Variables.Environment Variables Overview
Kit uses an
.env.local file in the boilerplate app directory for all configuration. This file is created during installation by copying .env.example.bash
cp apps/boilerplate/.env.example apps/boilerplate/.env.local
Variables follow the Next.js convention:
- Server-only variables — Available only in API routes and Server Components (e.g.,
DATABASE_URL,CLERK_SECRET_KEY) - Client variables — Prefixed with
NEXT_PUBLIC_, available in both server and client code (e.g.,NEXT_PUBLIC_APP_URL)
Variables prefixed with
NEXT_PUBLIC_ are bundled into the client JavaScript and visible to anyone who inspects your site. Never put secrets, API keys, or passwords in NEXT_PUBLIC_ variables.Essential Configuration
These are the settings you should configure first to get a working development environment.
1
App URL
Set your application URL. In development, this is typically
localhost:3000:bash
NEXT_PUBLIC_APP_URL=http://localhost:3000
In production, set this to your actual domain:
bash
NEXT_PUBLIC_APP_URL=https://your-app.com
This URL is used for metadata, OAuth callbacks, and webhook URLs.
2
Database
Configure your database connection. Choose the option matching your setup from installation.
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nextjs_dev
DIRECT_URL=postgresql://postgres:postgres@localhost:5432/nextjs_dev
.env.example
# Database Configuration
# ============================================
# You have TWO options for database setup:
#
# Option 1: Docker Compose (Recommended for Local Development)
# - Run: docker-compose up -d
# - Use URLs below (localhost)
# - No external setup needed
#
# Option 2: Supabase (Recommended for Production)
# - Managed PostgreSQL with built-in features
# - Use pooled connection URL (port 6543)
# - Example: postgresql://postgres.[project]:[password]@aws-1-eu-central-1.pooler.supabase.com:6543/postgres?pgbouncer=true&connection_limit=1
# Option 1: Docker Compose URLs (local development)
# Uncomment these when using docker-compose up -d:
# DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nextjs_dev
# DIRECT_URL=postgresql://postgres:postgres@localhost:5432/nextjs_dev
# Option 2: Supabase URLs (production)
# Use the pooled connection URL with pgbouncer parameters
DATABASE_URL=
# Direct connection URL for migrations only - no pooling
# Example: postgresql://postgres.[project]:[password]@aws-1-eu-central-1.pooler.supabase.com:5432/postgres
DIRECT_URL=
3
Authentication
Clerk handles all authentication. You need a publishable key and a secret key from the Clerk Dashboard.
bash
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
You can skip this step initially and use
pnpm dev:no-clerk to develop without Clerk. Kit provides a mock authentication system for development. Configure Clerk when you are ready to test real authentication flows.The remaining Clerk variables have sensible defaults:
bash
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/login
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/register
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
4
Pricing Model
Kit supports two pricing models. Choose the one that fits your business:
.env.example
# ============================================
# PRICING MODEL SELECTION (REQUIRED)
# ============================================
# Choose ONE model for your application
# IMPORTANT: Only ONE can be active at a time!
#
# Options:
# - credit_based: AI/API-heavy apps with variable costs
# - classic_saas: Standard SaaS with fixed costs per user
NEXT_PUBLIC_PRICING_MODEL=credit_based
credit_based— For AI/API-heavy apps where usage varies. Users buy credits and consume them per action.classic_saas— Traditional subscription pricing with monthly/yearly plans and fixed feature sets.
You can only have one active at a time. The app validates this at startup and will show an error if the configuration is invalid.
Color Themes
Kit ships with 9 color themes. Change your entire application's look by setting a single environment variable:
bash
COLOR_THEME=default
Available themes:
.env.example
# COLOR THEME CONFIGURATION
# ============================================
# Choose your application's color scheme
# Available themes:
# - default : Classic blue (professional and trustworthy)
# - ocean : Deep blue and teal (maritime and tech startups)
# - forest : Emerald green (sustainable and eco-friendly SaaS)
# - sunset : Warm orange and pink (creative design tools)
# - midnight : Deep purple and blue (premium enterprise look)
# - coral : Vibrant pink and coral (modern consumer apps)
# - slate : Neutral gray with blue accents (professional business tools)
# - aurora : Bright cyan and turquoise (cutting-edge tech platforms)
# - crimson : Bold red and violet (performance and analytics)
#
# To add a custom theme:
# 1. Create a new CSS file in src/styles/themes/your-theme.css
# 2. Import it in src/app/globals.css
# 3. Add theme name to AVAILABLE_THEMES in src/styles/themes/themes.ts
COLOR_THEME=default
Each theme provides both light and dark mode variants:
src/styles/themes/themes.ts
export const THEME_METADATA: Record<ThemeName, ThemeMetadata> = {
default: {
name: 'default',
displayName: 'Default Blue',
description: 'Classic blue theme - professional and trustworthy',
primaryColor: '#3b82f6',
category: 'blue',
},
ocean: {
name: 'ocean',
displayName: 'Ocean',
description: 'Deep blue and teal - perfect for maritime and tech startups',
primaryColor: '#0891b2',
category: 'teal',
},
forest: {
name: 'forest',
displayName: 'Forest',
description: 'Emerald green - ideal for sustainable and eco-friendly SaaS',
primaryColor: '#10b981',
category: 'green',
},
sunset: {
name: 'sunset',
displayName: 'Sunset',
description: 'Warm orange and pink - creative and energetic design tools',
primaryColor: '#f97316',
category: 'warm',
},
midnight: {
name: 'midnight',
displayName: 'Midnight',
description: 'Deep purple and blue - premium enterprise look',
primaryColor: '#6366f1',
category: 'purple',
},
coral: {
name: 'coral',
displayName: 'Coral',
description: 'Vibrant pink and coral - modern consumer applications',
primaryColor: '#ec4899',
category: 'pink',
},
slate: {
name: 'slate',
displayName: 'Slate',
description: 'Neutral gray with blue accents - professional business tools',
primaryColor: '#64748b',
category: 'neutral',
},
aurora: {
name: 'aurora',
displayName: 'Aurora',
description: 'Bright cyan and turquoise - cutting-edge tech platforms',
primaryColor: '#06b6d4',
category: 'teal',
},
crimson: {
name: 'crimson',
displayName: 'Crimson',
description: 'Bold red and violet - performance and analytics platforms',
primaryColor: '#dc2626',
category: 'red',
},
}
Changing the theme requires no code changes — just update
COLOR_THEME in apps/boilerplate/.env.local and restart the dev server. The theme system uses CSS custom properties, so all components automatically pick up the new colors.For creating custom themes, see Color Themes & Dark Mode.
Feature Flags
Kit uses environment variables as feature flags to enable or disable functionality.
AI Features
Control which AI features are available in your application:
.env.example
# ============================================
# AI CHAT BOT FEATURE FLAGS
# ============================================
# Two separate AI chat systems exist.
# Each system can be independently enabled/disabled.
# All features default to 'true' for backwards compatibility.
# Set to 'false' to disable specific features.
# ============================================
# AI CHAT FEATURES
# ============================================
# RAG Chat
# Dashboard route: /dashboard/chat-rag
# API routes: /api/ai/rag/*
# Features: Claude-style UI, Knowledge Base integration, Source Attribution
# Requires: pgvector database with FAQ chunks
NEXT_PUBLIC_AI_RAG_CHAT_ENABLED=true
# LLM Chat (Direct Chat)
# Dashboard route: /dashboard/chat-llm
# API routes: /api/ai/chat, /api/ai/stream
# Features: Clean Chat UI, Direct LLM conversation, Streaming
# Does NOT require FAQ (Rag Chat) database setup
NEXT_PUBLIC_AI_LLM_CHAT_ENABLED=true
# Vision Chat (Image Analysis in LLM Chat)
# Extends LLM Chat with image upload and analysis capabilities.
# Requires LLM Chat to be enabled. Only active when BOTH flags are true.
# Features: Drag & Drop, Paste, File picker for image analysis
NEXT_PUBLIC_AI_VISION_ENABLED=true
# PDF Chat (Document Analysis in LLM Chat)
# Extends LLM Chat with PDF upload and text extraction capabilities.
# Requires LLM Chat to be enabled. Only active when BOTH flags are true.
# Features: Drag & Drop, File picker, server-side text extraction, all providers
NEXT_PUBLIC_AI_PDF_CHAT_ENABLED=true
# Audio Input (Speech-to-Text in LLM Chat)
# Adds a microphone button for voice input via OpenAI Whisper.
# Requires LLM Chat to be enabled. Only active when BOTH flags are true.
# Features: Browser-native recording, real-time audio levels, auto-transcription
NEXT_PUBLIC_AI_AUDIO_INPUT_ENABLED=true
# Image Generation (Text-to-Image)
# Dashboard route: /dashboard/image-gen
# API route: /api/ai/image-gen
# Features: GPT Image models, multiple sizes/qualities/formats, transparent backgrounds
# Standalone feature — does NOT require LLM Chat to be enabled.
# Requires: OPENAI_API_KEY
NEXT_PUBLIC_AI_IMAGE_GEN_ENABLED=true
# Content Generator — Template-based text generation
# Dashboard route: /dashboard/content
# API route: /api/ai/generate-content
# Features: 5 templates (Email, Product, Blog, Social, Marketing), SSE streaming, tone/language/length options
# Standalone feature — does NOT require LLM Chat to be enabled.
NEXT_PUBLIC_AI_CONTENT_GEN_ENABLED=true
# ============================================
# COMMON CONFIGURATIONS
# ============================================
# Use these combinations based on your needs:
#
# 1. Full AI Features (Default):
# NEXT_PUBLIC_AI_RAG_CHAT_ENABLED=true
# NEXT_PUBLIC_AI_LLM_CHAT_ENABLED=true
#
# 2. RAG Chat Only:
# NEXT_PUBLIC_AI_RAG_CHAT_ENABLED=true
# NEXT_PUBLIC_AI_LLM_CHAT_ENABLED=false
#
# 3. LLM Chat Only:
# NEXT_PUBLIC_AI_RAG_CHAT_ENABLED=false
# NEXT_PUBLIC_AI_LLM_CHAT_ENABLED=true
#
# 4. No AI Features (Disable All):
# NEXT_PUBLIC_AI_RAG_CHAT_ENABLED=false
# NEXT_PUBLIC_AI_LLM_CHAT_ENABLED=false
Common configurations:
| Use Case | RAG Chat | LLM Chat | Vision | Audio | Image Gen | Content Gen | |
|---|---|---|---|---|---|---|---|
| Full AI Features | true | true | true | true | true | true | true |
| RAG Chat Only | true | false | false | false | false | false | false |
| LLM Chat Only | false | true | true | true | true | false | false |
| LLM Chat (text only) | false | true | false | false | false | false | false |
| Generators Only | false | false | false | false | false | true | true |
| No AI Features | false | false | false | false | false | false | false |
Vision Chat (
NEXT_PUBLIC_AI_VISION_ENABLED) requires LLM Chat to be enabled. If NEXT_PUBLIC_AI_LLM_CHAT_ENABLED is false, the vision flag has no effect.Audio Input (
NEXT_PUBLIC_AI_AUDIO_INPUT_ENABLED) requires LLM Chat to be enabled. If NEXT_PUBLIC_AI_LLM_CHAT_ENABLED is false, the audio input flag has no effect.Image Generation (
NEXT_PUBLIC_AI_IMAGE_GEN_ENABLED) is a standalone feature that requires OPENAI_API_KEY — it uses OpenAI's GPT Image models directly, regardless of the configured AI_PROVIDER.Content Generator (
NEXT_PUBLIC_AI_CONTENT_GEN_ENABLED) is a standalone feature — it uses the active AI provider for template-based text generation (email, product descriptions, blog outlines, social media posts, marketing copy).Blog
Enable or disable the blog functionality:
bash
NEXT_PUBLIC_ENABLE_BLOG=true
When set to
false, blog routes and navigation links are hidden.Demo Mode
Demo mode provides a fully functional demo without real API keys:
bash
NEXT_PUBLIC_DEMO_MODE=true
When enabled, Kit uses mock data for all external services (auth, payments, AI). This is useful for showcasing the product without connecting to live services. See the demo mode section in the Authentication Overview for details.
Service Configuration
Each integrated service requires its own set of environment variables. Configure them as you need each service.
| Service | Required Variables | Documentation |
|---|---|---|
| Clerk (Auth) | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY | Authentication |
| Supabase (DB) | DATABASE_URL, DIRECT_URL | Database |
| Lemon Squeezy (Payments) | LEMONSQUEEZY_API_KEY, LEMONSQUEEZY_STORE_ID, LEMONSQUEEZY_WEBHOOK_SECRET | Payments |
| Resend (Email) | RESEND_API_KEY, RESEND_FROM_EMAIL | Email Service |
| Vercel Blob (Storage) | BLOB_READ_WRITE_TOKEN | File Storage |
| Upstash (Redis) | UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN | Caching & Redis |
| AI Providers | AI_API_KEY (universal) or provider-specific: OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_AI_API_KEY, XAI_API_KEY | AI Integration |
For production, all services marked as required for your features must be configured. In development, Kit gracefully handles missing credentials by disabling the corresponding features or using mock data. All environment variables go in
apps/boilerplate/.env.local.Branding
Your app name, tagline, and metadata are configured in a single file:
src/config/site.ts
export const siteConfig = {
/** Your brand/product name */
name: 'nextsaas.ai Kit',
/** Short description for the homepage title tag */
tagline: 'AI-Native Next.js SaaS Boilerplate',
/** Name used for blog article title tags */
blogName: 'nextsaas.ai Blog',
/** Separator between page name and brand (En-dash is professional standard) */
separator: '–',
/** Base URL for metadata */
url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
/** Default description for pages without custom description */
description:
'Production-ready Next.js boilerplate with authentication, database, and modern UI components.',
/** Author information */
author: {
name: 'Jon Doe',
twitter: '@jondoe',
},
} as const
export type SiteConfig = typeof siteConfig
Update these values to match your product:
typescript
export const siteConfig = {
name: 'YourProduct',
tagline: 'Your Value Proposition Here',
blogName: 'YourProduct Blog',
// ...
}
This configuration is used across the application for:
- Page titles and SEO metadata
- Open Graph and Twitter card metadata
- Footer and navigation branding
- Email templates
Security Configuration
Kit includes several security-related environment variables:
bash
# CORS: Comma-separated list of allowed origins
ALLOWED_ORIGINS=http://localhost:3000
# CSP: Optional reporting endpoint for Content Security Policy violations
CSP_REPORT_URI=
# Cron: Secret for authenticating scheduled jobs
CRON_SECRET=
For production, set
ALLOWED_ORIGINS to your domain(s) and generate a strong CRON_SECRET:bash
# Generate a secure random string
openssl rand -base64 32
See the Security Overview for a full guide on configuring rate limiting, security headers, and input validation.
Configuration Validation
Kit validates critical configuration at startup. Specifically, the pricing model configuration is checked when the root layout renders:
- If
NEXT_PUBLIC_PRICING_MODELis set to an invalid value, the app shows a clear error message - If required variant IDs are missing for the selected pricing model, you will see a warning in the console
This validation happens automatically — you do not need to run any commands.