Skip to main content
Tutorial

Environment Variables Done Right: How I Manage Secrets Across Dev, Staging, and Prod

5 min read

Practical secrets management across dev, staging, and production for Next.js projects on Vercel

nextjsenvironmentvariablesvercelsecuritylaravel

Last week at 2:23 AM, I pushed a hotfix to a Laravel-Next.js hybrid app for a Dubai luxury car rental client. The build failed because I forgot to set DATABASE_URL in the staging environment. Two coffee-fueled hours later, I realized I’d hardcoded a production secret in next.config.js. If this sounds familiar — or terrifying — let’s talk about how to handle environment variables without losing your sanity.

Local Development: The Foundation I Never Skip

In 7 years of shipping UAE-focused apps (looking at you, Greeny Corner plant ID platform), I’ve learned secrets management starts locally. Here’s my setup:

  • Never check in .env.local files. Gitignore them aggressively.
  • Structure variables by convention, like NEXT_PUBLIC_* for client-side, DB_ for database connections.
  • Use TypeScript’s process.env types to catch mistakes early — wasted 6 hours once debugging why API_KEY was undefined because of a typo in three files.

For Next.js projects hosted on Vercel, I add a .vercel/.env.local file but never commit it. This lets me test production-like variables without exposing real values. Example:

javascript
// next.config.js
const nextConfig = {
  env: {
    API_URL: process.env.NODE_ENV === 'production' 
      ? 'https://api.prod-domain.ae'
      : 'https://api.dev-domain.ae'
  }
}

This one saved my ass during the DAS Holding corporate site rebuild when QA kept hitting the wrong API endpoints.

Staging vs Production: Automating the Difference

At my first UAE startup job, I accidentally deployed .env files to production for a Sharjah-based delivery app. The CTO threatened to ban me from the coffee machine forever. Now? I use these hard rules:

  1. Never reuse production secrets in staging. Period. One client wanted to “save money” by using the same Firebase API key for both environments — we had to rebuild their authentication system when a dev leak exposed 800+ user emails.
  2. Set environment-specific values in Vercel’s dashboard. For Tawasul Limo, I configured NEXT_PUBLIC_STRIPE_PUBLIC separately for preview, staging, and production deployments.
  3. Automate variable validation. Use cross-env in package.json scripts to enforce required variables before builds run:
json
"scripts": {
  "build:prod": "cross-env -V NODE_ENV=production NEXT_PUBLIC_ANALYTICS_ID REQUIRED_VAR_1 REQUIRED_VAR_2 next build"
}

Security: The Mistakes I Won't Repeat

In 2023, I built a bilingual real estate app for Reach Home Properties where the client insisted on storing database credentials in Vercel’s UI. It worked fine until their intern pasted the production DATABASE_URL into a public GitHub issue. Now I:

  • Rotate secrets every 6 months using a shared Bitwarden vault.
  • Use Vercel’s built-in encrypted environment variables for production.
  • For super-sensitive values (think 3rd-party banking APIs), implement runtime fetching through a secure proxy instead of static env vars.

Never store files with secrets in /public folder — learned that the hard way when a client’s staging URL exposed .env.local via GitHub history.

Frequently Asked Questions

How do I manage environment variables in Vercel for multiple projects?

For solo projects (like my UAE restaurant menu QR generator), I use the CLI command vercel env add to sync values manually. For enterprise clients with compliance needs, set them through the UI and lock permissions under the "Environment Variables" section.

Should I store secrets locally if I'm working in a team?

Only if you want teammates to rage-quit. Use managed solutions: Bitwarden shared folders for passwords, Vercel env for app variables, and .env.example templates for non-secret config. Once I tried Dropbox syncing .env.local files — disaster waiting to happen.

How can I check if secrets are exposed in git history?

Run git log -S 'DATABASE_URL' to search historical commits. Found some in an Abu Dhabi logistics company’s repo three years back. Had to rewrite history with git filter-branch and invalidate 27 API keys.

Can I use environment variables for client-side React Native logic?

Carefully! In Expo SDK 54 for Greeny Corner’s AI plant identification feature, I exposed only NEXT_PUBLIC_ANALYTICS_ID and masked other values behind API endpoints. If it can be decompiled from the app bundle, it doesn’t deserve to be a secret.

I’ve been managing environment variables the messy, real-world way for over 7 years — from Laravel backend setups in Kuwaiti banks to Vercel deployments for Riyadh startups. When your app scales from 10 to 10,000 UAE users overnight, you need systems that work when it counts. If you’re tired of 502 Bad Gateway errors at midnight, book a free consultation — we’ll build your secrets pipeline before it becomes an incident report.

S

Sarah

Senior Full-Stack Developer & PMP-Certified Project Lead — Abu Dhabi, UAE

7+ years building web applications for UAE & GCC businesses. Specialising in Laravel, Next.js, and Arabic RTL development.

Work with Sarah