Environment variables
Copy .env.example to ignored .env.local. Real credentials must not be written to tracked defaults. The site factory does not copy local credentials, databases or Git history. API environment validation lives in apps/api/lib/env.ts; errors report field names and categories, not secret values.
Core settings
| Variable | Purpose |
|---|---|
ENVIRONMENT | development, staging or production |
APP_NAME | API/Worker brand; align with product metadata |
APP_ORIGIN | Bare trusted origin; HTTPS outside development |
PUBLIC_SITE_URL | Public canonical, social, sitemap and RSS origin |
DATABASE_URL | Private local/CLI connection; complete preview requires loopback |
BETTER_AUTH_SECRET | Unique secret, at least 32 characters; placeholders rejected outside development |
DOCS_SITE_URL | Optional public docs URL; omitted local builds are noindex |
WEBSITE_ORIGIN, WEBSITE_DOCS_URL, WEBSITE_DEMO_URL | Public build values for the separate official website |
PUBLIC_* values can enter public assets. VITE_APP_NAME, appearance and default language are derived from product configuration. Do not expose private keys through client build variables.
Provider groups
Google and GitHub client ID/secret pairs must be complete or empty. Stripe requires its secret, subscription webhook secret and both monthly Price IDs as a complete group. Optional Pro annual pricing requires that group. Credit packs require their own configured catalogue and a distinct credits webhook secret; real prices, cycles and mode must be checked against the provider.
Production email needs RESEND_API_KEY and a verified RESEND_EMAIL_FROM. Marketing contact sync also requires its own webhook secret and two different topic IDs. Rewardful secrets are server-only and the public referral key is a separate value. Optional Turnstile needs both the public site key and private verification secret. Configuration validation does not prove provider permissions or delivery.
BETTER_AUTH_SECRETS supports versioned authentication rotation. Review the detailed Chinese maintenance guide before changing live keys; do not rotate keys during ordinary translation work.
Worker bindings
HYPERDRIVE_CACHED, HYPERDRIVE_UNCACHED, STORAGE, TASK_QUEUE, API/App service bindings and assets are resource objects, not environment strings. Development derives its two Hyperdrive connections from the local database URL. Local storage/queue state lives in .local/workerd/ and is never copied to a new site.
Local mail, marketing and operator capture bindings are development fixtures. They do not enable real external delivery. Optional modules require their documented migrations in an isolated acceptance database; the normal preview is not automatically upgraded.
bun run config:check
bun run config:check --jsonTarget-specific checks read the supplied environment; they do not convert local values into production settings. No cloud publish or real product connection is part of the current iteration.