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.

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.local

This 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), not http://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.local can leak into production because .env.local loads in both modes.
  • A committed .env default 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 a VITE_ 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 typeWritten to
Public (VITE_)apps/web/.env.production
Secret / privateapps/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 localhost or development URLs remain in VITE_SITE_URL or 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

GoalIn the Dev Tool
See production valuesMode selector → production
Find broken valuesDisplay Invalid only / filter invalid
Find missing required valuesScan Required badges
Spot shadowed valuesFilter overridden → check Override Chain
Avoid leaking secretsCheck Public/Private tag; keep secrets out of VITE_
Export configCopy env file to clipboard

For the full catalog of every variable and its meaning, see Environment Variables Reference.