Skip to Content
Iris Saas Kit documentation is under construction.
TechnicalEnvironment Variables

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:

  1. Next.js Environment - Frontend configuration in .env.local
  2. Convex Environment - Backend configuration via Convex dashboard
  3. 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

  1. Clone repository
  2. Install dependencies: pnpm install
  3. Initialize Convex: npx convex dev
  4. Setup authentication: npx @convex-dev/auth
  5. Create .env.local with frontend variables
  6. Configure remaining environment variables
  7. 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