Environment Variables
Complete guide to setting up environment variables for both Next.js frontend and Convex backend.
🏗️ Environment Architecture
Dual Environment Setup
The boilerplate uses two separate environment systems:
- Next.js Environment - Frontend configuration in
.env.local
- Convex Environment - Backend configuration via Convex dashboard
- Centralized Management -
convex/envs.ts
for type-safe access
Environment Variable Flow
Convex Dashboard → convex/envs.ts → Convex Functions
↓
Next.js .env.local → Components & Pages
🔧 Convex Environment Variables
Centralized Configuration
All Convex environment variables managed in convex/envs.ts
:
// convex/envs.ts
// Convex Internal
export const CONVEX_SITE_URL = process.env.CONVEX_SITE_URL!; // Auto-generated
export const SITE_URL = process.env.SITE_URL!; // Frontend URL
// Developer Access
export const DEVELOPER_ROLE_PASSKEY =
process.env.DEVELOPER_ROLE_PASSKEY ?? 'passkey';
// Email Integration
export const AUTH_RESEND_KEY = process.env.AUTH_RESEND_KEY!;
export const EMAIL_DOMAIN = process.env.EMAIL_DOMAIN!; // e.g. @mysite.com
// Google OAuth
export const AUTH_GOOGLE_CLIENT_ID = process.env.AUTH_GOOGLE_CLIENT_ID!;
export const AUTH_GOOGLE_CLIENT_SECRET = process.env.AUTH_GOOGLE_CLIENT_SECRET!;
// Stripe Billing
export const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY ?? 'UNSET';
export const STRIPE_WEBHOOK_SECRET =
process.env.STRIPE_WEBHOOK_SECRET ?? 'UNSET';
// Team Notifications (Optional)
export const COMMS_PLATFORM: 'slack' | 'discord' | 'UNSET' = 'discord';
export const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN ?? 'UNSET';
export const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN ?? 'UNSET';
Variable Categories
Required Variables (using !
)
- Immediate failure if not set
- Critical for functionality
- Examples:
AUTH_RESEND_KEY
,AUTH_GOOGLE_CLIENT_ID
Optional Variables (using ?? "UNSET"
)
- Graceful degradation if not set
- Feature-specific - app works without them
- Examples:
STRIPE_SECRET_KEY
,SLACK_BOT_TOKEN
Auto-Generated Variables
- Set by Convex CLI during setup
- Do not manually configure
- Examples:
CONVEX_SITE_URL
Setting Convex Variables
Via Convex Dashboard:
# Navigate to your Convex project
npx convex dashboard
# Go to Settings → Environment Variables
# Add each variable with its value
Via CLI:
# Set individual variables
npx convex env set AUTH_RESEND_KEY your-resend-api-key
npx convex env set AUTH_GOOGLE_CLIENT_ID your-google-client-id
# List all variables
npx convex env list
🌐 Next.js Environment Variables
Required Frontend Variables
Create .env.local
in project root:
# .env.local
# Convex Connection (Required)
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
# Node Environment (Automatic)
NODE_ENV=development
Public vs Private Variables
Public Variables (NEXT_PUBLIC_*
)
- Exposed to browser - accessible in client components
- Only use for non-sensitive data
- Required for Convex connection
// components/ConvexClientProvider.tsx
const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
Private Variables
- Server-side only - not exposed to browser
- Used in server components and API routes
- Sensitive data like API keys
// app/(authenticated)/dev-app/layout.tsx
export const metadata: Metadata = {
icons: {
icon:
process.env.NODE_ENV === 'development' ? '/logo-dev.svg' : '/logo.svg',
},
};
Development vs Production
Development-specific features:
// Conditional rendering based on environment
{process.env.NODE_ENV === "development" && (
<div className="mb-8">
<h2>Developer Tools</h2>
<p>This section only appears in development</p>
</div>
)}
📋 Complete Environment Setup
Required Environment Variables
Core System
# Auto-generated by Convex
CONVEX_SITE_URL=https://your-deployment.convex.cloud
SITE_URL=https://your-frontend-domain.com
# Frontend connection
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
Authentication
# Resend for email delivery
AUTH_RESEND_KEY=re_xxxxxxxxxx
EMAIL_DOMAIN=@yoursite.com
# Google OAuth
AUTH_GOOGLE_CLIENT_ID=xxxxx.apps.googleusercontent.com
AUTH_GOOGLE_CLIENT_SECRET=GOCSPX-xxxxx
Optional Features
# Stripe billing (optional)
STRIPE_SECRET_KEY=sk_test_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx
# Developer access (optional)
DEVELOPER_ROLE_PASSKEY=your-secret-passkey
# Team notifications (optional)
SLACK_BOT_TOKEN=xoxb-xxxxx
DISCORD_BOT_TOKEN=xxxxx
Environment Setup Process
1. Initial Convex Setup
# Initialize Convex project
npx convex dev
# This creates:
# - CONVEX_SITE_URL (auto-generated)
# - Basic project configuration
2. Authentication Setup
# Configure Convex Auth
npx @convex-dev/auth
# This sets:
# - SITE_URL (your frontend URL)
# - Basic auth configuration
3. Manual Configuration
# Add remaining variables via dashboard or CLI
npx convex env set AUTH_RESEND_KEY your-key
npx convex env set AUTH_GOOGLE_CLIENT_ID your-id
npx convex env set AUTH_GOOGLE_CLIENT_SECRET your-secret
4. Frontend Configuration
# Create .env.local
echo "NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud" > .env.local
✅ Environment Validation
Built-in Validation System
Environment status checking for critical services:
// convex/core/stripe.devQueries.ts
export const getStripeEnvReady = developerQuery({
args: {},
handler: async () => {
const webhookKey =
!!STRIPE_WEBHOOK_SECRET && STRIPE_WEBHOOK_SECRET !== 'UNSET';
const secretKey = !!STRIPE_SECRET_KEY && STRIPE_SECRET_KEY !== 'UNSET';
return {
webhookKey,
secretKey,
};
},
});
UI Environment Alerts
Visual environment status in admin interface:
// Stripe configuration alert component
const StripeEnvironmentAlert = ({ stripeEnv, isLoading }: Props) => {
const allEnvReady = stripeEnv?.webhookKey && stripeEnv?.secretKey;
const hasAnyEnvIssue = stripeEnv && (!stripeEnv.webhookKey || !stripeEnv.secretKey);
if (hasAnyEnvIssue) {
return (
<div className="mb-6 p-4 bg-destructive/10 border border-destructive/20 rounded-lg">
<h3 className="text-sm font-medium text-destructive mb-2">
Stripe Configuration Required
</h3>
<ul className="space-y-2">
<li className="flex items-center gap-2 text-sm">
{stripeEnv?.secretKey ? (
<CheckCircle className="h-4 w-4 text-green-600" />
) : (
<XCircle className="h-4 w-4 text-destructive" />
)}
<code>STRIPE_SECRET_KEY</code>
<span>{stripeEnv?.secretKey ? "✓ Configured" : "Not configured"}</span>
</li>
</ul>
</div>
);
}
return null;
};
🔒 Security Best Practices
Environment Security
Never Commit Secrets
# .gitignore includes
.env*
# This protects:
# - .env.local
# - .env.development
# - .env.production
Use Appropriate Variable Types
// ✅ Good - Public data only
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
// ❌ Bad - Never expose secrets
NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_xxxxx // DON'T DO THIS
Validate Required Variables
// ✅ Good - Fail fast with !
export const AUTH_RESEND_KEY = process.env.AUTH_RESEND_KEY!;
// ✅ Good - Graceful degradation
export const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY ?? 'UNSET';
Production Deployment
Vercel Deployment
# Set environment variables in Vercel dashboard
# or via CLI:
vercel env add NEXT_PUBLIC_CONVEX_URL
vercel env add NODE_ENV
Convex Production
# Deploy to production
npx convex deploy --prod
# Set production environment variables
npx convex env set --prod AUTH_RESEND_KEY your-prod-key
npx convex env set --prod STRIPE_SECRET_KEY your-prod-key
🔍 Troubleshooting
Common Issues
Missing NEXT_PUBLIC_CONVEX_URL
Error: ConvexReactClient missing URL
Solution: Add to .env.local
Convex Variables Not Loading
Error: process.env.AUTH_RESEND_KEY is undefined
Solution: Set via npx convex env set
Wrong Environment
Development variables in production
Solution: Use --prod
flag for production variables
Environment Debugging
Check Convex Variables
# List all variables
npx convex env list
# Check specific variable
npx convex env get AUTH_RESEND_KEY
Check Next.js Variables
// In a component or page
console.log('CONVEX_URL:', process.env.NEXT_PUBLIC_CONVEX_URL);
console.log('NODE_ENV:', process.env.NODE_ENV);
🚀 Development Workflow
Local Development Setup
- Clone repository
- Install dependencies:
pnpm install
- Initialize Convex:
npx convex dev
- Setup authentication:
npx @convex-dev/auth
- Create
.env.local
with frontend variables - Configure remaining environment variables
- Start development:
pnpm dev
Environment-Specific Features
- Development mode: Extra developer tools and logging
- Production mode: Optimized builds and error handling
- Feature toggles: Based on environment variable availability
- Service degradation: Graceful handling of missing optional variables
Last updated on