Chapter 9 of 11
Real applications need configuration — database URLs, API keys, secret tokens. You never hardcode these into your source code. Instead, Next.js uses environment variables stored in .env files.
ANALOGY
Real-world analogy: A safe in the office. Sensitive information (your database password, your Stripe secret key) is like money in a safe. You don't leave it on your desk (in your code) for everyone to see. Environment variables are the safe — only your application has access, and it's never committed to GitHub.
# Database connection
DATABASE_URL="postgresql://username:password@localhost:5432/mydb"
# Third-party service secrets (NEVER share these)
STRIPE_SECRET_KEY="sk_live_abc123..."
SENDGRID_API_KEY="SG.xyz..."
# Public variables — safe to expose in the browser (prefix with NEXT_PUBLIC_)
NEXT_PUBLIC_SITE_NAME="NelsonLabs"
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_live_..."| File | When it loads |
|---|---|
| .env | All environments |
| .env.local | Local only — add to .gitignore! Never commit this. |
| .env.development | Only when running npm run dev |
| .env.production | Only when running npm run build |
// In API routes and Server Components — all variables are available
const dbUrl = process.env.DATABASE_URL; // ✅ Never sent to browser
const apiKey = process.env.STRIPE_SECRET_KEY; // ✅ Safe
const siteName = process.env.NEXT_PUBLIC_SITE_NAME; // ✅ Also available server-side"use client";
// ✅ Available in the browser — you chose to make it public
const siteName = process.env.NEXT_PUBLIC_SITE_NAME;
// ❌ This is undefined in the browser — and would expose your secret if it weren't!
const secretKey = process.env.STRIPE_SECRET_KEY; // Returns undefinedWARNING
Critical security rule. Never prefix sensitive values with NEXT_PUBLIC_. That prefix bundles the value into the JavaScript file that gets sent to every user's browser. Anyone can open DevTools and read it. API keys, database passwords, and secret tokens must never have this prefix.
/** @type {import('next').NextConfig} */
const nextConfig = {
// Allow Next.js to optimise images from these external domains
images: {
domains: ["images.unsplash.com", "cdn.myapp.com"],
},
// Automatically redirect old URLs to new ones
async redirects() {
return [
{
source: "/old-course-page",
destination: "/courses",
permanent: true, // 301 redirect — tells Google the page moved permanently
},
];
},
};
module.exports = nextConfig;