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.localfiles. Gitignore them aggressively. - •Structure variables by convention, like
NEXT_PUBLIC_*for client-side,DB_for database connections. - •Use TypeScript’s
process.envtypes to catch mistakes early — wasted 6 hours once debugging whyAPI_KEYwasundefinedbecause 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:
// 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:
- 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.
- Set environment-specific values in Vercel’s dashboard. For Tawasul Limo, I configured
NEXT_PUBLIC_STRIPE_PUBLICseparately for preview, staging, and production deployments. - Automate variable validation. Use
cross-envin package.json scripts to enforce required variables before builds run:
"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.