Skip to Content
LaunchfastDocs

Environment variables

Every environment variable the kit reads, whether it's required, and where its value comes from.

Locally, variables live in .env.local in the project root (never committed). In production, they're set in Vercel under Settings → Environment Variables. npm run setup fills in both.

After changing one: restart npm run dev locally, or redeploy on Vercel.

App

VariableRequiredExampleWhat it's for
NEXT_PUBLIC_APP_URLYeshttps://yourdomain.comThe app's public address. Used for sign-in callbacks, email links, the checkout return URL, canonical URLs, share images and the sitemap. No trailing slash. Locally http://localhost:3000
BETTER_AUTH_SECRETYes44 random charactersSigns session cookies. Generate with openssl rand -base64 32. Changing it signs everyone out

Database

VariableRequiredExampleWhat it's for
DATABASE_URLYespostgresql://user:pass@ep-….neon.tech/neondb?sslmode=requireNeon Postgres connection string

Payments (Dodo)

VariableRequiredExampleWhat it's for
DODO_PAYMENTS_API_KEYYesAPI key with Write access, from Developer → API Keys
DODO_PAYMENTS_ENVIRONMENTYestest_mode or live_modeMust match the key's mode. Anything other than live_mode means test mode
DODO_PAYMENTS_WEBHOOK_SECRETFor payments to unlock planswhsec_…Signing secret of your webhook endpoint. Setup sets it on Vercel when deploying
DODO_PRODUCT_<PLAN>One per planpdt_…Each plan's Dodo product ID. The names come from productEnv in src/config.ts; the example plans use DODO_PRODUCT_STARTER and DODO_PRODUCT_PRO

Email (Resend)

VariableRequiredExampleWhat it's for
RESEND_API_KEYIn production, for email sign-inre_…Without it: emails print to the terminal locally, and email sign-in is hidden in production
EMAIL_FROMWith Resend"Your Product <hello@yourdomain.com>"Sender. The domain must be verified in Resend. Quote it in .env.local

Social sign-in

Each provider turns on only when both its variables are set.

VariableRequiredWhat it's for
GOOGLE_CLIENT_IDNoGoogle OAuth client ID
GOOGLE_CLIENT_SECRETNoGoogle OAuth client secret
GITHUB_CLIENT_IDNoGitHub OAuth app client ID
GITHUB_CLIENT_SECRETNoGitHub OAuth app client secret

Repository delivery

Both must be set to turn the feature on. See Selling access to a GitHub repo.

VariableRequiredExampleWhat it's for
GITHUB_REPONoyour-org/your-productThe private repository buyers are invited to
GITHUB_REPO_TOKENNogithub_pat_…Fine-grained token with Administration: Read and write on that repository

Formatting .env.local

.env.local
# One per line, no spaces around =
DATABASE_URL=postgresql://user:pass@host/db?sslmode=require

# Quote values with spaces or special characters
EMAIL_FROM="Your Product <hello@yourdomain.com>"

Common mistakes

  • The file must be named exactly .env.local (not .env.local.txt, which Windows may add when you save from Notepad), in the same folder as package.json.
  • No spaces around =.
  • Copy keys in full, without line breaks or trailing spaces.
  • NEXT_PUBLIC_ variables are built into the page. Changing one needs a rebuild, not just a restart, in production.

Never commit secrets

.env.local is in .gitignore. If you ever commit a key by accident, deleting the file isn't enough: it stays in Git history. Rotate the key in the service's dashboard (create a new one, delete the old one).

On this page