Configuration
Complete guide to configuring environment variables and application settings
Configuration
This guide covers all environment variables and configuration options for the Next.js Full-Stack Starter Kit.
Environment Variables
All configuration is done through environment variables in the .env file.
Note: Security: Never commit your
.envfile to version control. Use.env.exampleas a template.
Required Configuration
These variables are essential for the application to run:
Database
DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require"Description: PostgreSQL connection string
Options:
- Neon:
postgresql://user:password@ep-xxxxx.region.aws.neon.tech/neondb?sslmode=require - Supabase: Get from Project Settings > Database
- Local:
postgresql://postgres:password@localhost:5432/yourdb
Note: SSL Mode: Production databases usually require
?sslmode=require. Local databases may not need it.
For detailed instructions on switching between database providers (Neon, Supabase, Local), see the Database Providers Guide.
Authentication
BETTER_AUTH_SECRET="your-secret-key-here-min-32-characters"
BETTER_AUTH_URL="http://localhost:3000"
NEXT_PUBLIC_APP_URL="http://localhost:3000"BETTER_AUTH_SECRET:
- Generate with:
openssl rand -base64 32 - Must be at least 32 characters
- Keep this secret and secure
- Use different values for dev/staging/production
BETTER_AUTH_URL:
- The base URL of your application
- Used for authentication callbacks
- Development:
http://localhost:3000 - Production:
https://yourdomain.com
NEXT_PUBLIC_APP_URL:
- Public-facing app URL
- Exposed to the browser (starts with
NEXT_PUBLIC_) - Used for generating links in emails
- Should match
BETTER_AUTH_URL
Admin Setup
FIRST_ADMIN_EMAIL="admin@example.com"Description: Email address for the first admin user
Usage:
- Sign up with this email
- Run
pnpm admin:setup - User will be promoted to admin role
Note: Security: After creating your first admin, you can remove this variable or use the admin dashboard to manage roles.
OAuth Providers (Optional)
Google OAuth
GOOGLE_CLIENT_ID="your-google-client-id.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="your-google-client-secret"Setup:
- Go to Google Cloud Console
- Create or select a project
- Enable Google+ API
- Configure OAuth consent screen
- Create OAuth 2.0 credentials (Web application)
- Add authorized redirect URI:
- Dev:
http://localhost:3000/api/auth/callback/google - Prod:
https://yourdomain.com/api/auth/callback/google
- Dev:
GitHub OAuth
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"Setup:
- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in details:
- Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:3000/api/auth/callback/github
- Homepage URL:
- Get Client ID and generate Client Secret
Email Configuration (Optional)
Choose one email provider for sending transactional emails:
EMAIL_PROVIDER="nodemailer" # Options: nodemailer | resend | sendgrid | mailgunNodemailer (SMTP)
Default option, works with any SMTP server:
EMAIL_PROVIDER="nodemailer"
EMAIL_HOST="smtp.gmail.com"
EMAIL_PORT="587"
EMAIL_USER="your-email@gmail.com"
EMAIL_PASS="your-app-password"
EMAIL_SECURE="false" # Use "true" for port 465
EMAIL_FROM="Your App <noreply@yourapp.com>"Gmail Setup:
- Enable 2-factor authentication
- Generate an App Password
- Use the app password in
EMAIL_PASS
Other SMTP Providers:
- Outlook:
smtp.office365.com:587 - Yahoo:
smtp.mail.yahoo.com:587 - Custom SMTP: Use your provider's settings
Note: Gmail OAuth2 (alternative):
bash GMAIL_CLIENT_ID="your-google-client-id" GMAIL_CLIENT_SECRET="your-google-client-secret" GMAIL_REFRESH_TOKEN="your-refresh-token"
Resend
Modern email API with great DX:
EMAIL_PROVIDER="resend"
RESEND_API_KEY="re_xxxxxxxxxxxx"
EMAIL_FROM="Your App <noreply@yourdomain.com>"Setup:
- Create account at Resend
- Verify your domain
- Get API key from API Keys page
Pricing: 100 emails/day free, then $20/month for 50,000 emails
SendGrid
Popular email service by Twilio:
EMAIL_PROVIDER="sendgrid"
SENDGRID_API_KEY="SG.xxxxxxxxxxxx"
EMAIL_FROM="Your App <noreply@yourdomain.com>"Setup:
- Create account at SendGrid
- Verify your domain
- Create API key in Settings > API Keys
Pricing: 100 emails/day free, then starts at $15/month
Mailgun
Reliable email service for developers:
EMAIL_PROVIDER="mailgun"
MAILGUN_API_KEY="your-mailgun-api-key"
MAILGUN_DOMAIN="mg.yourdomain.com"
MAILGUN_REGION="us" # or "eu"
EMAIL_FROM="Your App <noreply@mg.yourdomain.com>"Setup:
- Create account at Mailgun
- Add and verify your domain
- Get API key from Settings > API Keys
Pricing: 5,000 emails/month free for 3 months
Stripe (Optional)
For subscription payments and billing:
STRIPE_SECRET_KEY="sk_test_xxxxxxxxxxxx"
STRIPE_PUBLISHABLE_KEY="pk_test_xxxxxxxxxxxx"
STRIPE_WEBHOOK_SECRET="whsec_xxxxxxxxxxxx"Setup:
- Create account at Stripe
- Get API keys from Dashboard > Developers > API keys
- Set up webhooks:
- Go to Dashboard > Developers > Webhooks
- Add endpoint:
https://yourdomain.com/api/stripe/webhook - Select events:
customer.subscription.*,invoice.*,payment_intent.* - Get webhook signing secret
Stripe Price IDs
Configure your product price IDs:
STRIPE_PRICE_PRO_MONTHLY="price_xxxxxxxxxxxx"
STRIPE_PRICE_PRO_YEARLY="price_xxxxxxxxxxxx"
STRIPE_PRICE_STARTUP_MONTHLY="price_xxxxxxxxxxxx"
STRIPE_PRICE_STARTUP_YEARLY="price_xxxxxxxxxxxx"To get Price IDs:
- Create products in Stripe Dashboard > Products
- Add pricing (monthly and yearly)
- Copy the Price ID (starts with
price_)
Note: Test Mode: Use test mode keys (starts with
sk_test_andpk_test_) during development. Switch to live keys in production.
File Uploads (Optional)
UploadThing
UPLOADTHING_TOKEN="eyJhcHBJZCI6xxxxxxxxxxxx"Setup:
- Create account at UploadThing
- Create an app
- Copy token from Dashboard
Pricing: 2GB storage + 2GB bandwidth free, then pay-as-you-go
Features:
- Automatic image optimization
- CDN distribution
- File type validation
- Size limits
AI Writing Assistant (Optional)
OPENROUTER_API_KEY="sk-or-v1-xxxxxxxxxxxx"Description: API key for AI-powered blog writing features
Setup:
- Create account at OpenRouter
- Get API key from Keys page
- Add credits (optional - free models available!)
Models Used:
- Free models (no cost):
meta-llama/llama-3.2-3b-instruct:freegoogle/gemini-flash-1.5
- Paid models (optional):
anthropic/claude-3.5-sonnetopenai/gpt-4-turbo
Note: Free Tier: The starter kit uses FREE models by default. No API costs!
Testing (Optional)
Pre-configured test user credentials for E2E tests:
TEST_USER_EMAIL="test-user@example.com"
TEST_USER_PASSWORD="TestUser123!@#"
TEST_ADMIN_EMAIL="test-admin@example.com"
TEST_ADMIN_PASSWORD="TestAdmin123!@#"Usage: Run pnpm test:seed to create these test users, then use them in Playwright tests.
Additional Configuration
Node Environment
NODE_ENV="development" # development | productionAuto-set by Next.js, but you can override if needed.
Rate Limiting
Rate limiting is configured in code (src/lib/rate-limit.ts), not environment variables. See Security > Rate Limiting for customization.
Security Headers
Security headers are configured in next.config.ts. See Security > Headers for details.
Configuration by Environment
Development (.env.local)
DATABASE_URL="postgresql://localhost:5432/mydb"
BETTER_AUTH_SECRET="dev-secret-change-me"
BETTER_AUTH_URL="http://localhost:3000"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
FIRST_ADMIN_EMAIL="dev@example.com"
# Optional: Use test mode for services
STRIPE_SECRET_KEY="sk_test_..."
EMAIL_PROVIDER="nodemailer"Staging
DATABASE_URL="postgresql://staging-db-url"
BETTER_AUTH_SECRET="staging-secret-32-chars-min"
BETTER_AUTH_URL="https://staging.yourdomain.com"
NEXT_PUBLIC_APP_URL="https://staging.yourdomain.com"
# Use test mode Stripe
STRIPE_SECRET_KEY="sk_test_..."Production
DATABASE_URL="postgresql://production-db-url"
BETTER_AUTH_SECRET="production-secret-SUPER-SECURE"
BETTER_AUTH_URL="https://yourdomain.com"
NEXT_PUBLIC_APP_URL="https://yourdomain.com"
# Use live Stripe keys
STRIPE_SECRET_KEY="sk_live_..."
STRIPE_PUBLISHABLE_KEY="pk_live_..."
# Configure all integrations
GOOGLE_CLIENT_ID="..."
GITHUB_CLIENT_ID="..."
RESEND_API_KEY="..."
UPLOADTHING_TOKEN="..."Environment Variable Validation
The starter kit validates required environment variables during setup. Run:
pnpm project:setupThis checks for:
- ✅ Database connection
- ✅ Auth secrets
- ✅ Required URLs
- ⚠️ Warns about missing optional configs
Security Best Practices
1. Never Commit Secrets
# .gitignore already includes:
.env
.env.local
.env*.local2. Rotate Secrets Regularly
- Change
BETTER_AUTH_SECRETevery 90 days - Rotate API keys periodically
- Update passwords and tokens
3. Use Different Secrets Per Environment
Never reuse production secrets in development/staging.
4. Minimum Secret Length
BETTER_AUTH_SECRET: minimum 32 characters- Passwords: minimum 12 characters
- API tokens: as provided by the service
5. Environment-Specific Configuration
# ✅ Good
# Each environment has unique values
BETTER_AUTH_SECRET="prod-abc123..." # Production
BETTER_AUTH_SECRET="stag-xyz789..." # Staging
# ❌ Bad
# Same secret in all environmentsTroubleshooting
"Invalid environment variable" errors
- Check
.envfile exists - Verify all required variables are set
- Ensure no extra spaces around
= - Restart dev server after changes
Database connection fails
- Verify
DATABASE_URLformat - Check database is running
- Test SSL requirements (
?sslmode=require) - Verify credentials are correct
Auth redirects fail
- Ensure
BETTER_AUTH_URLmatches your domain - Check trailing slashes (none should be present)
- Verify OAuth redirect URLs match exactly
Emails not sending
- Check email provider credentials
- Verify
EMAIL_FROMdomain is verified - Test with a simple SMTP provider first
- Check application logs for errors