Docs

Search documentation

Jump to a documentation page.

PricingMarketingApp

Search documentation

Jump to a documentation page.

Environment

Environment variables

Canonical template: .env.example at the monorepo root. Values below are grouped the same way; unset optional vars unless noted.

Database

VariableRequiredNotes
DATABASE_URLYesPostgres connection string for Drizzle and Better Auth.

Better Auth

VariableRequiredNotes
AUTH_SECRETYesLong random secret (openssl rand -base64 32).
BETTER_AUTH_URLYes in prodBase URL of apps/web (e.g. http://localhost:3001).
BETTER_AUTH_TRUSTED_ORIGINSRecommended locallyComma-separated allowed Origin values. If the browser’s origin is not listed, Better Auth returns Invalid origin. For pnpm dev:marketing (3000) + pnpm dev:web (3001), include both http://localhost:3000 and http://localhost:3001.
BETTER_AUTH_COOKIE_DOMAINOptionale.g. .yournextsaas.xyz for shared cookies across subdomains.
AUTH_REQUIRE_EMAIL_VERIFICATIONOptionalSet to 1 only when Resend (or another mailer) is configured.

Cross-app origins (Vite)

Used by appHref() / marketingHref() in packages/core (landing Sign in, Dashboard, pricing → app, etc.).

VariableNotes
VITE_APP_ORIGINProduct app base URL, no trailing slash. If unset, appHref("/auth/sign-in") becomes a path on the current site only — on marketing that route does not exist (404).
VITE_MARKETING_ORIGINMarketing base URL for links from the product app back to pricing/legal.

Documentation site (apps/docs)

Developer docs are a separate app in apps/docs (TanStack Start, default dev port 3002). Deploy it to https://docs.yourdomain.com (its own Vercel project or server build).

VariableWhereNotes
VITE_SITE_URLDocs app buildCanonical / Open Graph base for the docs host only, no trailing slash (e.g. https://docs.yournextsaas.xyz).
VITE_DOCS_ORIGINMarketing + apps/web buildsSame public URL as the docs site, so docsHref() in landing/product emits absolute links. Local: http://localhost:3002.

Local two-app setup (recommended)

With marketing on 3000 and the product app on 3001, set at least:

  • BETTER_AUTH_URL=http://localhost:3001
  • BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000,http://localhost:3001
  • VITE_APP_ORIGIN=http://localhost:3001
  • VITE_MARKETING_ORIGIN=http://localhost:3000

Copy from .env.example at the repo root. Restart dev servers after changes (Vite reads VITE_* at startup).

Use the same host you put in the URL (localhost vs 127.0.0.1) everywhere; they are different origins for cookies and Better Auth.

Transactional email (Resend)

VariableNotes
RESEND_API_KEYWithout it, auth emails are skipped (dev logs URL in console).
EMAIL_FROMFrom address; quote if it contains spaces.

OAuth (optional)

Set both client id and secret per provider. Callback URLs:

  • {BETTER_AUTH_URL}/api/auth/callback/google
  • {BETTER_AUTH_URL}/api/auth/callback/github
Variable
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET

Marketing / SEO (Vite)

VariableNotes
VITE_SITE_URLPublic marketing origin, no trailing slash.
VITE_GOOGLE_SITE_VERIFICATIONSearch Console meta content.
VITE_TWITTER_SITEX handle without @.

Platform admin

VariableNotes
ADMIN_USER_IDSComma-separated user ids allowed for /admin + Better Auth admin plugin.

Stripe

VariableNotes
STRIPE_SECRET_KEYTest key by default; live requires STRIPE_ALLOW_LIVE=1.
STRIPE_WEBHOOK_SECRETSigning secret for POST /api/stripe/webhook.
STRIPE_ALLOW_LIVESet to 1 only when deliberately using live keys.
STRIPE_PRICE_STARTERPrice id (price_...), not product id.
STRIPE_PRICE_PROSame.

See Stripe & billing for checkout, webhooks, and local testing.

Seeding (optional)

VariableNotes
SEED_BULK_ORGSExtra org count for bulk seed (max 25).

See Database seeding.