Environment variables contain sensitive configuration. Handle them carefully to prevent accidental exposure.
Server vs. Client Variables
In Next.js, only variables prefixed with NEXT_PUBLIC_ are exposed to the browser:
# .env.local
# Server-only (never sent to browser)
DATABASE_URL="postgresql://..."
STRIPE_SECRET_KEY="sk_live_..."
API_SECRET="..."
# Public (embedded in client bundle)
NEXT_PUBLIC_STRIPE_KEY="pk_live_..."
NEXT_PUBLIC_API_URL="https://api.example.com"Validating Required Variables
// lib/env.ts
import { z } from "zod";
const envSchema = z.object({
DATABASE_URL: z.string().url(),
STRIPE_SECRET_KEY: z.string().startsWith("sk_"),
// Add all required variables
});
export const env = envSchema.parse(process.env);
// Now use env.DATABASE_URL instead of process.env.DATABASE_URLCommon Mistakes
- Logging secrets: Never log environment variables
- Client exposure: Don't use secrets without
NEXT_PUBLIC_on the client - Hardcoding: Don't commit secrets to version control
- String interpolation: Be careful with template strings in client code
What VibeCheck Detects
- VC-SEC-001: Hardcoded API keys and secrets
- VC-SEC-002: Secrets exposed to client code
- VC-SEC-003: Missing environment validation