Sajt · Docs

Environment variables

Every env var by group, where it lives (Convex deployment vs Vercel), and the dev-fallback principle that lets most integrations run unset.

This page lists variable names and purpose only — never values. Do not commit real keys; per-feature runbooks (SETUP.md, DEPLOY.md, docs/billing-setup.md, docs/email-setup.md, docs/domain-system-plan.md) own the full setup steps.

Where vars live

Two homes:

  • Vercel / .env.local — frontend and build vars (anything NEXT_PUBLIC_*, plus the Clerk client/server keys read by the Next.js app and middleware).
  • The Convex deployment — server-only secrets used inside Convex actions (AI, Stripe, Resend, the Vercel domains API). Set them with:
npx convex env set NAME value            # dev
npx convex env set NAME value --prod     # production

CLERK_JWT_ISSUER_DOMAIN is the one var that must be set in both places — the Next.js app and the Convex deployment — because Convex validates the convex JWT template independently. See Auth & permissions.

The dev-fallback principle

Most integrations run in dev / mock mode until their credentials are set, so the whole app (and CI) works locally without secrets:

  • No OPENROUTER_API_KEY → AI is disabled; the deterministic generator and the rest of the product still work fully.
  • No RESEND_API_KEY → transactional email is silently skipped (invites fall back to copy-link).
  • No Stripe keys → billing and payments are gated off (dev simulate paths).
  • No VERCEL_API_TOKEN / VERCEL_PROJECT_ID → the domain connect/buy flow returns deterministic "connected" results (dev fallback), testable without credentials.
  • No NEXT_PUBLIC_SITES_DOMAIN → platform subdomains are dormant; sites stay reachable at the /site/<slug> path.

Core (Convex client)

VarWherePurpose
CONVEX_DEPLOYMENTauto (convex dev)Selects the dev deployment
NEXT_PUBLIC_CONVEX_URLauto (convex dev / deploy)Convex client URL
NEXT_PUBLIC_CONVEX_SITE_URLoptionalOverride; otherwise derived from NEXT_PUBLIC_CONVEX_URL (lib/site/convexSiteUrl.ts)
NEXT_PUBLIC_APP_URLVercel / .env.local (+ Convex for domains)The app's own base URL
NEXT_PUBLIC_APP_HOSToptionalThe app's own host so middleware skips custom-domain lookups for it
CONVEX_DEPLOY_KEYVercel (production build only)Lets the Vercel build run convex deploy

Clerk (auth — required)

VarWherePurpose
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYVercel / .env.localClerk client key
CLERK_SECRET_KEYVercel / .env.local (secret)Clerk server key
CLERK_JWT_ISSUER_DOMAIN.env.local and the Convex deploymentIssuer of the convex JWT template

AI — OpenRouter (optional; on the Convex deployment)

OPENROUTER_API_KEY powers all AI (generation/polish, the chat assistant, vision, dictation). The model overrides are all optional — defaults live in convex/generation/models.ts.

VarPurpose
OPENROUTER_API_KEYThe single key for all AI (server-side only)
OPENROUTER_MODEL_HEAVYGeneration / FAQ / offers tier override
OPENROUTER_MODEL_AGENTAI chat "smart" override (default = heavy)
OPENROUTER_MODEL_FASTAI chat "fast" override (default = small)
OPENROUTER_MODEL_SMALLSingle-field rewrite override
OPENROUTER_MODEL_TINYSEO meta / brief extraction override
OPENROUTER_MODEL_SHORTENOptional override for the shorten action
OPENROUTER_VISION_MODELPhoto placement + chat image vision override
OPENROUTER_STT_MODELVoice dictation (Whisper) override
OPENROUTER_IMAGE_MODEL_PRO / _FREEPaid / free image model override
TAVILY_API_KEYEnables the chat's read-only webSearch tool

See the AI system.

Email — Resend (optional; on the Convex deployment)

VarPurpose
RESEND_API_KEYEnables transactional email (invites, lead + booking notifications)
RESEND_FROMThe "from" identity for sent mail

No key = email is silently skipped (docs/email-setup.md).

Billing & payments — Stripe (optional; on the Convex deployment)

VarPurpose
STRIPE_SECRET_KEYStripe API key (billing + Connect payments)
STRIPE_BILLING_WEBHOOK_SECRETVerifies /api/stripe/billing-webhook
STRIPE_CONNECT_WEBHOOK_SECRETVerifies /api/stripe/connect-webhook (online card pay)
STRIPE_WEBHOOK_SECRETVerifies /api/stripe/domain-webhook (domain purchase)
PAYMENTS_ALLOW_DEV_SIMULATEDev-only: simulate a successful payment (never in prod)

Price ids and the operator runbook live in docs/billing-setup.md.

Domains & hosting — Vercel (optional)

VarWherePurpose
DOMAIN_PROVIDERConvexvercel to use the real registrar; otherwise the dev mock
VERCEL_API_TOKENConvexConnect / buy domains via the Vercel API
VERCEL_PROJECT_IDConvexTarget Vercel project for domain attach
VERCEL_TEAM_IDConvexVercel team scope
NEXT_PUBLIC_SITES_DOMAINVercel / .env.localSubdomain zone for published sites (e.g. the platform domain)
VERCEL_ENVauto (Vercel)Set to production only on the prod deployment; gates the landing lab

See Deployment and docs/domain-system-plan.md. No domain secrets are ever stored in Convex tables.

Misc & native shells (optional)

VarPurpose
NEXT_PUBLIC_SUPPORT_EMAILPublic support address shown in the UI
NEXT_PUBLIC_DESKTOP_DMG_URLDownload link shown on /download
SAJT_DESKTOP_URLWeb app the Tauri desktop shell loads
APPLE_TEAM_ID / IOS_BUNDLE_IDiOS build-time identifiers

On this page