Environment Variables
How secrets reach your app without living in your code — and the two-copies rule behind the most common “works on my laptop” bug.
What they actually are
Named values that live next toyour code instead of inside it — think of them as your app's settings drawer. Two kinds of things belong there: secrets (API keys, database passwords — things that must never end up on GitHub) and things that differ between your laptop and your live site.
Your code says “connect using whatever SUPABASE_URLis” — and each place the app runs supplies its own value. Same code everywhere, different settings per place.
The file: .env.local
On your laptop, environment variables live in a file called .env.local in your project's root — one NAME=value per line:
NEXT_PUBLIC_SUPABASE_URL=https://abcdefgh.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_xxxxxxxx
SUPABASE_SECRET_KEY=sb_secret_xxxxxxxxThe crucial property: this file is gitignored on purpose. It never gets committed, never gets pushed, never appears on GitHub — even in a public repo. That's the entire trick: code travels, secrets don't.
💡 tipYou'll rarely edit this file by hand. Tell Claude “put these values in .env.local and make sure it's gitignored” and it handles both.
Public vs. secret values
In Next.js, a variable starting with NEXT_PUBLIC_gets baked into the code that ships to visitors' browsers — anyone can see it. That's correct for values designed to be public (Supabase's publishable key is public by design, protected by Row Level Security). Everything without the prefix stays on the server, invisible to browsers.
🔑The naming rule:
Never put NEXT_PUBLIC_in front of a real secret — that one prefix is the difference between “server-only” and “published to every visitor.” If you're unsure about a value, ask Claude: “should this env variable be public or server-only?”
The two-copies rule
Because .env.local never leaves your laptop, your live site knows nothing about it. Every value your app needs exists in two places: the file on your laptop, and your host's settings for the live site:
🩹The #1 deploy gotcha:
“Works on localhost, breaks on Vercel” is almost always a variable that exists in .env.local but was never added in Vercel. When it happens, ask Claude:
List every environment variable this project needs so I can
check they're all set in Vercel.💡 tipVercel only reads env variables at build time — after adding or changing one, hit Redeploy or the change won't take effect.