src/env.ts — open it for the source of truth.
This page mirrors that file, organized by category, so you can copy-paste your way
to a working .env.local (and prod env) in one pass.
A few conventions:
- Required vars throw at startup if missing or empty.
- Optional vars default to empty string and the consuming module no-ops gracefully.
NEXT_PUBLIC_*vars are shipped to the browser. Never put secrets in them.- Set
SKIP_ENV_VALIDATION=trueto bypass validation in CI build steps that don’t need real values (Vercel preview builds, Docker image bakes, etc.).
Core
The bare minimum for the app to boot.| Variable | Required | Default | Description |
|---|---|---|---|
NODE_ENV | no | development | development / production / test. Set automatically by your runtime. |
DATABASE_PROVIDER | no | postgres | Reserved for future drivers. Only postgres works in v0.1. |
DATABASE_URL | yes | — | Postgres connection string. Use the pooled URL in production. |
BETTER_AUTH_SECRET | yes | — | 16+ char secret for session signing. Generate: openssl rand -base64 32. |
BETTER_AUTH_URL | no | — | Full URL (with scheme) of your deployed app. Required in production for OAuth callbacks. |
NEXT_PUBLIC_APP_URL | no | http://localhost:3000 | Used by sitemap, OG images, OAuth redirects. Set to your prod URL. |
NEXT_PUBLIC_APP_NAME | no | vibestrap | Display name in titles, OG metadata, emails. |
ADMIN_EMAILS | no | '' | Comma-separated list of admin emails. Auto-promoted to role: 'admin' on signup. |
OAuth
Each provider is independent — set both id + secret to enable, leave blank to hide.| Variable | Required | Default | Description |
|---|---|---|---|
GOOGLE_CLIENT_ID | no | '' | Google OAuth client id. Enables “Sign in with Google”. |
GOOGLE_CLIENT_SECRET | no | '' | Google OAuth secret (server-only). |
NEXT_PUBLIC_GOOGLE_CLIENT_ID | no | '' | Mirror of GOOGLE_CLIENT_ID. Needed for client-side One-Tap. Safe to expose. |
GITHUB_CLIENT_ID | no | '' | GitHub OAuth app id. Enables “Sign in with GitHub”. |
GITHUB_CLIENT_SECRET | no | '' | GitHub OAuth secret. |
RESEND_API_KEY is empty.
| Variable | Required | Default | Description |
|---|---|---|---|
RESEND_API_KEY | no | '' | Resend API key (re_…). Powers verification + welcome + reset-password emails. |
RESEND_FROM_EMAIL | no | [email protected] | From: address. Switch to your verified domain in production. |
RESEND_REPLY_TO_EMAIL | no | '' | Optional Reply-To: header. |
RESEND_AUDIENCE_ID | no | '' | Resend Audience id for newsletter (when newsletter.provider = 'resend'). |
Newsletter — Beehiiv
Only used ifsiteConfig.newsletter.provider = 'beehiiv'.
| Variable | Required | Default | Description |
|---|---|---|---|
BEEHIIV_API_KEY | no | '' | Beehiiv v2 API key. |
BEEHIIV_PUBLICATION_ID | no | '' | Publication id (pub_…). |
Payments — Stripe
Default provider. Only the*_PRICE_* ids you actually sell need to be set.
| Variable | Required | Default | Description |
|---|---|---|---|
STRIPE_SECRET_KEY | yes (if active) | '' | sk_test_… / sk_live_…. |
STRIPE_WEBHOOK_SECRET | yes (if active) | '' | whsec_… from the Stripe dashboard webhook config. |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | no | '' | pk_…. Needed for Stripe.js / Elements. |
STRIPE_PRICE_VIBESTRAP_PROMO | no | '' | Price id for the vibestrap promo tier ($49). |
STRIPE_PRICE_VIBESTRAP_STANDARD | no | '' | Price id for the vibestrap standard tier ($99). |
STRIPE_PRICE_PRO_MONTHLY | no | '' | Buyer-app Pro plan, monthly. |
STRIPE_PRICE_PRO_YEARLY | no | '' | Buyer-app Pro plan, yearly. |
STRIPE_PRICE_LIFETIME | no | '' | Buyer-app Lifetime tier. |
STRIPE_PRICE_CREDITS_BASIC | no | '' | Credit pack — basic. |
STRIPE_PRICE_CREDITS_STANDARD | no | '' | Credit pack — standard. |
STRIPE_PRICE_CREDITS_PREMIUM | no | '' | Credit pack — premium. |
STRIPE_PRICE_CREDITS_ENTERPRISE | no | '' | Credit pack — enterprise. |
Payments — Paddle
Only used ifsiteConfig.payment.provider = 'paddle'.
| Variable | Required | Default | Description |
|---|---|---|---|
PADDLE_API_KEY | yes (if active) | '' | Paddle API key. |
PADDLE_WEBHOOK_SECRET | yes (if active) | '' | Webhook signing secret. |
PADDLE_PRICE_VIBESTRAP_PROMO | no | '' | Price id for promo tier. |
PADDLE_PRICE_VIBESTRAP_STANDARD | no | '' | Price id for standard tier. |
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN | no | '' | Public client token for Paddle.js. |
NEXT_PUBLIC_PADDLE_ENV | no | sandbox | sandbox or production. Match your API key. |
Payments — Lemon Squeezy
Only used ifsiteConfig.payment.provider = 'lemonsqueezy'.
| Variable | Required | Default | Description |
|---|---|---|---|
LEMON_SQUEEZY_API_KEY | yes (if active) | '' | API key from Lemon Squeezy dashboard. |
LEMON_SQUEEZY_STORE_ID | yes (if active) | '' | Numeric store id. |
LEMON_SQUEEZY_WEBHOOK_SECRET | yes (if active) | '' | Webhook signing secret. |
LEMON_VARIANT_VIBESTRAP_PROMO | no | '' | Variant id for promo tier. |
LEMON_VARIANT_VIBESTRAP_STANDARD | no | '' | Variant id for standard tier. |
Payments — Creem
Only used ifsiteConfig.payment.provider = 'creem'.
| Variable | Required | Default | Description |
|---|---|---|---|
CREEM_API_KEY | yes (if active) | '' | Creem API key. |
CREEM_WEBHOOK_SECRET | yes (if active) | '' | Webhook signing secret. |
CREEM_PRICE_VIBESTRAP_PROMO | no | '' | Price id for promo tier. |
CREEM_PRICE_VIBESTRAP_STANDARD | no | '' | Price id for standard tier. |
AI providers
Phase 2 lights these up. v0.1 ships themock provider so the demo pages stream
fake tokens without keys.
| Variable | Required | Default | Description |
|---|---|---|---|
AI_PROVIDER | no | mock | mock / openrouter / openai / anthropic / replicate / fal. |
OPENROUTER_API_KEY | no | '' | OpenRouter key (gateway to most LLMs). |
OPENROUTER_BASE_URL | no | https://openrouter.ai/api/v1 | Override only if self-hosting a gateway. |
OPENAI_API_KEY | no | '' | OpenAI key (sk-…). |
OPENAI_BASE_URL | no | https://api.openai.com/v1 | Override for Azure OpenAI or compat endpoints. |
ANTHROPIC_API_KEY | no | '' | Anthropic key (sk-ant-…). |
ANTHROPIC_BASE_URL | no | https://api.anthropic.com | Override for Bedrock / proxy. |
REPLICATE_API_TOKEN | no | '' | Replicate API token for image / audio models. |
FAL_KEY | no | '' | fal.ai key for fast image generation. |
Storage (S3 / R2)
Stub in v0.1 — wire if you need uploads or signed downloads.| Variable | Required | Default | Description |
|---|---|---|---|
S3_ENDPOINT | no | '' | Endpoint URL. AWS S3, Cloudflare R2, MinIO all work. |
S3_REGION | no | '' | Bucket region. R2 uses auto. |
S3_ACCESS_KEY_ID | no | '' | Access key id. |
S3_SECRET_ACCESS_KEY | no | '' | Secret access key. |
S3_BUCKET | no | '' | Bucket name. |
S3_PUBLIC_URL | no | '' | Public CDN base URL for served objects. |
Anti-bot — Cloudflare Turnstile
Set both keys to enable Turnstile on signup, forgot-password, and newsletter forms.| Variable | Required | Default | Description |
|---|---|---|---|
TURNSTILE_SECRET_KEY | no | '' | Server-side verification secret. |
NEXT_PUBLIC_TURNSTILE_SITE_KEY | no | '' | Public site key for the widget. |
Customer service
One widget at a time, picked bysiteConfig.customerService.provider. Each widget
self-gates on its env vars.
| Variable | Required | Default | Description |
|---|---|---|---|
NEXT_PUBLIC_CRISP_WEBSITE_ID | no | '' | Crisp website id (UUID). |
NEXT_PUBLIC_TAWK_PROPERTY_ID | no | '' | tawk.to property id. |
NEXT_PUBLIC_TAWK_WIDGET_ID | no | '' | tawk.to widget id. |
NEXT_PUBLIC_INTERCOM_APP_ID | no | '' | Intercom workspace id. |
NEXT_PUBLIC_CHATWOOT_WEBSITE_TOKEN | no | '' | Chatwoot website token. |
NEXT_PUBLIC_CHATWOOT_BASE_URL | no | https://app.chatwoot.com | Self-hosted Chatwoot URL if you run your own. |
Affiliate
Set the matching var(s) for whichever provider is active insiteConfig.affiliate.provider.
The internal provider needs no env vars.
| Variable | Required | Default | Description |
|---|---|---|---|
NEXT_PUBLIC_AFFONSO_PROGRAM_ID | no | '' | Affonso program id. |
NEXT_PUBLIC_REWARDFUL_API_KEY | no | '' | Rewardful public API key. |
NEXT_PUBLIC_TOLT_API_KEY | no | '' | Tolt public API key. |
Analytics
Each script renders only when its env var is set. Mix and match freely.| Variable | Required | Default | Description |
|---|---|---|---|
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID | no | '' | GA4 measurement id (G-…). |
NEXT_PUBLIC_POSTHOG_KEY | no | '' | PostHog project key. |
NEXT_PUBLIC_POSTHOG_HOST | no | https://us.i.posthog.com | EU users: https://eu.i.posthog.com. |
NEXT_PUBLIC_PLAUSIBLE_DOMAIN | no | '' | Plausible site domain. |
NEXT_PUBLIC_PLAUSIBLE_HOST | no | https://plausible.io | Self-hosted Plausible URL if applicable. |
NEXT_PUBLIC_UMAMI_WEBSITE_ID | no | '' | Umami website id. |
NEXT_PUBLIC_UMAMI_HOST | no | https://cloud.umami.is | Self-hosted Umami URL if applicable. |
NEXT_PUBLIC_CLARITY_PROJECT_ID | no | '' | Microsoft Clarity project id (heatmaps + session replay). |
NEXT_PUBLIC_YANDEX_METRIKA_ID | no | '' | Yandex Metrika counter id (digits only). |
Search-engine site verification
Each emits a<meta> tag in <head> via Next.js metadata.verification,
proving ownership in the matching webmaster console. Server-side env vars (no
NEXT_PUBLIC_ prefix). Empty values render no tag.
| Variable | Required | Default | Description |
|---|---|---|---|
GOOGLE_SITE_VERIFICATION | no | '' | Google Search Console — content value of the google-site-verification meta tag. |
BING_SITE_VERIFICATION | no | '' | Bing Webmaster Tools — content value of the msvalidate.01 meta tag. |
YANDEX_SITE_VERIFICATION | no | '' | Yandex Webmaster — content value of the yandex-verification meta tag. |
License delivery
Where the buyer-download endpoint redirects after a successful purchase.| Variable | Required | Default | Description |
|---|---|---|---|
LICENSE_DOWNLOAD_URL | no | '' | URL pattern with {key} placeholder. Typically a private GitHub release tarball or S3 signed URL. |
Misc
| Variable | Required | Default | Description |
|---|---|---|---|
NEXT_PUBLIC_DEMO_MODE | no | false | Set true to hide real payment + auth and show the read-only demo overlay. |
See also
- Vercel deployment — where to paste these in production.
- Cloudflare deployment —
wrangler secret putfor each secret. - Configuration —
siteConfigtoggles that switch which providers read which keys.