Environment variables
Per-project secrets encrypted at rest and injected into every preview container at start.
Setting variables
Open a project and click the Variables tab. Add a key/value pair, save, then redeploy — the next build has the new env. No rebuild of existing previews; variables are read when the container boots.
Built-in variables
PreviewDrop sets these for every container, on top of whatever you add:
| Variable | What it holds |
|---|---|
PORT | TCP port your app must listen on. Do not hardcode a port — this value changes per container. |
NEXTAUTH_URL | Automatically set to the live preview URL. NextAuth / Auth.js picks this up with no extra config. |
AUTH_URL | Same as NEXTAUTH_URL — set for frameworks that use AUTH_URL instead. |
Per-branch overrides
Every variable has a default value (applies to every preview) and can optionally be overridden per branch. Use this when you want the main branch pointed at a staging DB but feature branches pointed at an isolated one.
In the Variables tab, click the ellipsis next to a variable and choose Add override → pick the branch pattern. Branch patterns support exact matches (main) and globs (feature/*).
Importing and exporting
Paste a .env file directly into the Variables tab with Import from .env. Export is the inverse — a signed, time-limited download so you can move config between projects without passing secrets through Slack.
Secrets-in-Git? Don't.
.envfiles if you commit them. Secrets committed to Git are already leaked — PreviewDrop can't un-leak them. Put real secrets only in the Variables tab.Common recipes
Branch-isolated databases with Neon
Neon branch integration# Default (trunk): use a shared staging DB DATABASE_URL=postgres://u:p@ep-shared.neon.tech/app # Override for feature/*: Neon creates a branch DB per git branch # Set via Neon's GitHub integration, then reference the secret here DATABASE_URL=${NEON_BRANCH_DB_URL}
Auth callbacks (NextAuth / Auth.js)
NextAuth / Auth.js# NEXTAUTH_URL and AUTH_URL are set automatically — no variable needed. # Add *.previews.previewdrop.dev as an allowed redirect URI in your OAuth provider.
CORS for a separate frontend calling a preview API
Django / Rails / Express# Hardcode the preview subdomain pattern in your CORS config: ALLOWED_ORIGINS=https://*.previews.previewdrop.dev
Feature flag SDK key scoped to previews
GrowthBook / LaunchDarkly# Use a dedicated preview-env SDK key so flag changes don't affect production LD_SDK_KEY=sdk-preview-...
Debugging a missing variable
If your app can't see a variable you set, try in order:
- Redeploy the preview — variables are injected at container start, not hot-reloaded.
- Check the build log for typos in your
ENVdirectives. A hardcodedENV PORT=8080in the Dockerfile overrides PreviewDrop's injectedPORT. - Confirm there's no branch override shadowing your value — branch overrides win over defaults.
If a variable still looks blank in the Variables tab after you saved it, it may have failed to decrypt (encryption key rotation, envelope corruption). Re-enter the value; the next save re-encrypts under the current key.