Env Files and Secrets Without Leaking Keys

repo/.env.example sits alongside your uncommitted .env file and .gitignore at the root of your Next.js project. This file acts as a single source of truth for every environment variable your application needs to run, without ever storing plaintext secrets that can leak to public or private version control repos. Unlike your actual .env file, which holds live, sensitive values for your local environment, this example file only contains placeholders, format guidance, and context that helps anyone working on the repo set up their local environment correctly in minutes.

Core variable mapping for this file

Every line in this file maps directly to a variable you define in your uncommitted .env file, as well as the variables you set in your deployment platform’s environment variable dashboard. The table below outlines the standard mapping structure you use for all projects, so you can add, remove, or update variables as your app evolves without breaking consistency for your team.

Env Files and Secrets Without Leaking Keys desk detail
Desk detail for this page — not a measured lab photo.
Variable name Expected value type Placeholder example Required for environment
`NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` String `pk_test_xxxxxxxxxxxxxxxxxxxxxxxx` All (local, staging, production)
`CLERK_SECRET_KEY` String `sk_test_xxxxxxxxxxxxxxxxxxxxxxxx` All (local, staging, production)
`DATABASE_URL` PostgreSQL connection string `postgresql://user:pass@localhost:5432/dbname?schema=public` Local + Staging + Production
`NEXT_PUBLIC_GOOGLE_ANALYTICS_ID` String `G-XXXXXXXXXX` Production only
`RESEND_API_KEY` String `re_xxxxxxxxxxxxxxxxxxxxxxxxxx` Staging + Production

You never input real, live keys into this file, even for test environments, to eliminate any risk of accidental commit. The placeholders are formatted to match the structure of real keys, so anyone filling out their local .env file can immediately spot if they are using a key with the wrong prefix or format. For example, the Clerk publishable key placeholder starts with `pk_test_`, so if a teammate tries to use a secret key (starting with `sk_test_`) for that variable, they catch the error before they even try to run the app. Illustrative example: If you have 12 unique environment variables across 3 deployment environments, this mapping cuts onboarding time for new contributors by 78% by eliminating back-and-forth questions about missing variables, typos in key formats, and incorrect scope settings for public vs private keys. You also use this mapping to separate public variables (prefixed with `NEXT_PUBLIC_` in Next.js, which are exposed to the client browser) from private variables, which only run on the server, so you never accidentally expose a sensitive secret to client-side code.

Single edit to pair it with git controls

The only persistent edit you need to make to your repo’s configuration to pair this .env.example file with end-to-end leak protection is adding two lightweight guardrails that take less than 90 seconds to set up. First, you add `*.env` to the top of your root .gitignore file, which tells git to ignore any file ending with .env, including .env.local, .env.development, .env.production, and any other environment-specific secret files you create for testing. This rule ensures that even if you accidentally run `git add .` when your local .env file has live secrets, git will never stage or commit that file to your repo. Second, you add a gitleaks pre-commit hook to your package.json scripts, which runs a full scan of all staged changes for any string that matches common secret patterns: API keys with standard prefixes, database connection strings with embedded credentials, AWS access keys, webhook signing secrets, and more. If the scan detects any potential secret, it blocks the commit immediately and shows you the exact file and line number of the match, so you can remove the sensitive value before it ever touches your remote repo. This setup aligns with the default security guardrails included when you spin up a project via Build Next Stack, so you don’t have to configure these controls from scratch if you use the official starter. You test the setup once after configuration by creating a test .env file with a fake secret key, running `git add .`, and confirming that git does not list the .env file as a staged change, and that the pre-commit hook blocks any attempt to commit a file with a fake secret string. You also run a one-time full scan of your existing repo history when you first set up the hook, to catch any accidental secrets that may have been committed before you implemented these guardrails, so you can rotate those keys immediately to eliminate risk.

Next time you open this .env.example file

When you come back to this file after you have deployed your app to staging and production and are ready to build new features, you use it as your first stop for any variable-related changes. For example, if you add a Stripe payment integration next sprint, you add `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` and `STRIPE_SECRET_KEY` to this file immediately after you add them to your local .env file, so you don’t forget to add those variables to your deployment platform’s environment settings before you push the new feature to staging. You also add short comments above any variables that have non-obvious requirements: for example, a comment above the `DATABASE_URL` line noting that local environments need to have SSL disabled for local PostgreSQL connections, while production connections require a SSL query parameter to connect to your managed Supabase or Neon database. Every quarter, you open this file to run a quick audit: you cross-reference every variable listed here with the variables set in your Vercel, Netlify, or AWS dashboard, and delete any variables that are no longer in use, to reduce your attack surface if your deployment account is ever accessed by an unauthorized party. When you onboard a new developer to the project, you point them directly to this file first, so they can copy all the placeholder lines to their own local .env file, fill in the real values from your team’s encrypted password manager, and get the app running locally in less than 5 minutes without you having to walk them through each variable individually. You never use this file to share real keys with teammates, even test ones: all sensitive values are shared exclusively via your team’s password manager, so there is no paper trail of secrets in your repo’s commit history, Slack messages, or email threads. Over time, this file evolves with your app, adding new variables as you integrate new tools, removing old ones as you deprecate features, and updating context comments as your deployment setup changes, so it always remains the single source of truth for environment variable requirements for everyone working on the project. You also use this file to generate pre-flight checklists for production deployments, so you never push a new feature that relies on a variable you forgot to add to your production environment settings.

Illustrative card for Env Files and Secrets Without Leaking Keys
Illustrative worksheet for this topic. Treat numbers as examples.