76 76. Step 3: Storing your private info (env files, etc)
As of Oct 22, 2026 · Official docs: Next.js environment variables
Private information such as passwords and API keys (which we discuss later) should never be stored in git, because git repositories are often shared with other people. For the same reason, passwords and API keys should never be typed directly into JavaScript code, or into code in any other programming language.
A typical web project connects to several outside services, and each one needs some “secret” information (a password, an API key, etc.) to authenticate (log in) to it. In this project, your Next.js app works with Supabase, Google sign-in (Google OAuth), the OpenAI API and Stripe.
76.1 Where each setting goes
Not every setting lives in the same place:
| Setting | Where it goes | When you set it |
|---|---|---|
| Your Supabase project’s URL and publishable key | .env.local, a file on your computer |
This step and Step 5: Setup Supabase |
| The OpenAI API key and the Stripe keys, which the Edge Functions use | Supabase’s servers, as secrets (npx supabase secrets set ...) |
Step 7: Set Up OpenAI API and Step 8: Set Up Stripe |
| The Google Client ID and Client Secret | The Supabase dashboard | Step 6: setup authentication (Google OAuth) |
The same two settings as in .env.local, for the live site |
Vercel’s website (Environment Variables) | Step 13: Deploy to Production |
| The settings for the automated tests (optional) | .env.test.local, a file on your computer |
Step 15: Automated Testing and Troubleshooting |
In this step you create just one file, .env.local.
76.2 Create .env.local
The project comes with a file named .env.example. It is a template: it lists the settings the app needs, with fake values that contain XXXX, and it starts with notes (lines that begin with #) that explain the file. It contains no real information, so it is safe for it to be in the repository.
In the terminal, cd to the project’s top-level folder (the one with package.json in it) and copy the template:
cp .env.example .env.localcp copies the first file to a new file with the second name. The name must be exactly .env.local, dots included. You fill in the real values in Step 5: Setup Supabase.
Files whose names start with a dot are hidden: a plain ls doesn’t list .env.local, but ls -a does. In VS Code’s file list, it appears as usual.
.env.local
The project’s .gitignore file lists the files that git should never commit. One of its lines is .env*.local, which matches every file whose name starts with .env and ends with .local: .env.local, .env.test.local and so on. So your real values stay on your computer.
The templates .env.example and .env.test.example don’t end in .local, so they are in the repository. That’s why they must only ever hold fake values.
.env.local secret?
Both settings in .env.local start with NEXT_PUBLIC_. Next.js builds those into the web pages that every visitor’s browser downloads, so they are meant to be public. That is why the publishable key goes here, and the secret keys never do: a secret key in .env.local could end up in a web page.
76.3 Older versions of this tutorial
The tutorial video and the original tutorial also copy .env.example to supabase/.env. You don’t need that file: the Edge Functions get their keys from Supabase secrets, which you set with npx supabase secrets set.
Practice Questions
Easy
Question 1 · True or false
It’s fine to store passwords and API keys in your git repository, so that your teammates can find them easily.
Question 2 · Multiple choice
Where should you keep an API key for this project while you develop on your computer?
- Typed directly into a JavaScript file
- In a
.envfile, such as.env.local, that is listed in.gitignore - In the project’s README, so teammates can find it
- In
.env.example
Question 3 · Short answer
The page says each integration needs “secret” information to authenticate to the remote system. What does “authenticate” mean here, and what kinds of secret information are used?
Question 4 · Short answer
What is the .env.example file for?
Question 5 · Short answer
What does the .gitignore file do, and how does it protect your .env files?
Medium
Question 6 · Write the command
You are in the project’s top-level folder. Write the command that creates the file .env.local from the template.
Question 7 · Short answer
Match each setting with the place where it goes.
| Setting | Place | |
|---|---|---|
| 1. Your Supabase URL and publishable key, to run the app on your computer | A. Supabase secrets (npx supabase secrets set) |
|
| 2. The OpenAI API key that an Edge Function uses | B. .env.local |
|
| 3. The Supabase secret key that the automated tests use | C. Vercel’s Environment Variables | |
| 4. Your Supabase URL and publishable key, for the live site | D. .env.test.local |
Question 8 · True or false
.env.example contains your real API keys, so it must never be committed to git.
Question 9 · Scenario
Maria runs cp .env.example .env.local and then ls, but .env.local isn’t in the list. Did the command fail?
Hard
Question 10 · Find the bug
Sam typed:
cp .env.example .env.localeWhat’s wrong, and why could it cause two different problems?
Question 11 · Scenario
Sam is in his home folder when he runs cp .env.example .env.local. He gets an error saying that .env.example doesn’t exist (“No such file or directory”). Why, and how does he fix it?
Question 12 · Scenario
Two weeks later, Maria has filled in .env.local with her real keys. To be “safe”, she runs cp .env.example .env.local again. What happens? Can git help her undo it?
Question 13 · Long answer
Why should secrets never be typed directly into your code? What does keeping them in .env files give you instead?
Question 14 · Scenario
Sam wants his automated tests to work, so he pastes his Supabase secret key into .env.local as NEXT_PUBLIC_SUPABASE_SECRET_KEY="sb_secret_...". .env.local is never committed to git, so he thinks the key is safe. Why is he wrong, and where should the key go?