Production Environment Variables
A step-by-step workflow for building a complete, valid production environment configuration using the Dev Tool's Environment Variables manager.
Getting production environment variables right is one of the most error-prone parts of shipping a SaaS app: a single missing secret, a leftover development URL, or a value that fails validation can break authentication, billing, or email in production. The Dev Tool's Environment Variables manager turns this into a checklist you can work through visually.
This guide walks you through building a correct production configuration. It assumes you have the Dev Tool running (pnpm --filter dev-tool dev) and open at http://localhost:3010/variables. If you haven't used the manager before, read Environment Variables first.
Never commit production secrets
This workflow prepares production values and validates them locally. Real production secrets (API keys, database URLs, signing secrets) belong in your hosting platform's environment settings — not in any committed file. The Dev Tool writes secrets only to git-ignored *.local files so you can test locally without leaking them.
Step 1 — Switch to Production Mode
Use the mode selector at the top-left and choose production. Everything on the page now reflects the production file chain, where later files win:
.env → .env.production → .env.local → .env.production.localThis matters because a value that looks correct in development may be shadowed (or missing) in production. Working in production mode shows you exactly what your production build will see.
Step 2 — Fix Every Invalid Variable
Click the Display Invalid only toggle (or filter by invalid). The manager validates each value against its schema — URLs must be URLs, ports must be numbers, enums must be one of the allowed values, and required variables must be present.
Work down the list until the Invalid chip reads 0. Common production fixes:
VITE_SITE_URL— set to your real HTTPS domain (e.g.https://app.example.com), nothttp://localhost:3000. Many features (emails, OAuth redirects, absolute links) derive URLs from this.- Auth secrets — provide the production values for your auth provider and any social providers you enabled.
- Billing — set the production keys and webhook secrets for your billing provider (Stripe or Polar).
- Email/SMTP — set the production
EMAIL_*values so transactional email works. You can verify these end-to-end from the Dev Tool's Emails page.
Step 3 — Confirm Required Variables Are Present
Filter the list so you can scan the Required badges. A required variable with no effective value in production mode is a deployment blocker. Because production mode already excludes development-only files, anything still empty here will be empty in production too.
Step 4 — Review the Override Chain for Surprises
Filter by overridden and inspect each variable's Override Chain. Overrides are where subtle production bugs hide:
- A development value in
.env.localcan leak into production because.env.localloads in both modes. - A committed
.envdefault may be silently overriding a value you intended to set per-mode.
For each overridden variable, confirm the winning file is the one you want for production. If a development-only value is winning, move it: put the production value in .env.production (public) or .env.production.local (secret), or remove the stray override.
Step 5 — Separate Public and Secret Values Correctly
Check each variable's Public / Private tag:
- Public variables are
VITE_-prefixed and inlined into the client bundle. Never put a secret in aVITE_variable — it ships to every browser. - Private variables are server-only and safe for secrets.
When you edit a value in production mode, the Dev Tool automatically routes it to the right file:
| Value type | Written to |
|---|---|
Public (VITE_) | apps/web/.env.production |
| Secret / private | apps/web/.env.production.local (git-ignored) |
So public production defaults become part of your committed config, while secrets stay local and out of git.
Step 6 — Export the Final Configuration
Once the Invalid chip is 0 and every required and overridden variable checks out, use Copy env file to clipboard (top-right). This copies the fully-resolved production configuration in KEY=value form.
Paste it into your hosting platform's environment settings:
- Keep only the values production actually needs — you generally do not paste public defaults that are already committed in
.env. - Always set secret values (auth, database, billing, email) directly in the platform, never in a committed file.
See Environment Setup and Deployment for platform-specific steps.
Step 7 — Verify Before You Ship
Before deploying, do a final pass in the Dev Tool:
- Invalid = 0 in production mode.
- No
localhostor development URLs remain inVITE_SITE_URLor related variables. - No secret sits in a
VITE_-prefixed variable. - Every required variable resolves to a value.
- The Emails page can render and send a test email with your production SMTP settings.
Quick Reference
| Goal | In the Dev Tool |
|---|---|
| See production values | Mode selector → production |
| Find broken values | Display Invalid only / filter invalid |
| Find missing required values | Scan Required badges |
| Spot shadowed values | Filter overridden → check Override Chain |
| Avoid leaking secrets | Check Public/Private tag; keep secrets out of VITE_ |
| Export config | Copy env file to clipboard |
For the full catalog of every variable and its meaning, see Environment Variables Reference.