Configuration
Manage global project settings and environment variables.
Configuration has three layers: code defaults in config.ts, environment variables for deployment settings and credentials, and supported admin overrides stored in SystemSetting.
Code defaults and admin overrides
appowns product identity and metadata defaults.i18ndefines enabled locales, currency defaults and theNEXT_LOCALEcookie.auth.passwordPolicydefines password requirements;teams.avatarColorsdefines generated avatar colors.mailingselects the mail adapter and default sender.analyticsselects the browser analytics adapter.payments.plansseeds the pricing catalog; saved changes in/app/admin/pricingtake precedence.feedback,roadmap,changelogandai.copilotconfigure optional product modules.
The admin module and template settings screens store supported overrides without editing config.ts. Server code uses getResolvedModules() and getResolvedTemplateSettings() from database when it needs those overrides. Reading config.ts directly only reads code defaults. Provider IDs and their TypeScript types live in packages/config/providers.ts; vendor implementations remain in their owning packages.
Environment settings
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SITE_URL | Public app origin, such as http://localhost:3000 locally |
DATABASE_URL | PostgreSQL connection string |
BETTER_AUTH_SECRET | Auth and signed-reference secret; use at least 32 random characters |
APP_ENCRYPTION_KEY | Key that encrypts saved provider secrets at rest; generated by setup:local, required wherever credentials are saved through the admin forms |
ADMIN_EMAILS | Comma-separated addresses granted admin role when they sign up |
MOCK_SERVICES | true explicitly selects mock payments, console mail, mock storage and mock AI |
PAYMENT_PROVIDER | Payment adapter; see Payments |
MAIL_PROVIDER | Mail adapter; see Email Providers |
AI_PROVIDER | AI adapter; see AI Providers |
STORAGE_PROVIDER | Storage adapter; see Storage |
S3_ENDPOINT, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY | S3-compatible connection |
NEXT_PUBLIC_AVATARS_BUCKET_NAME | Bucket permitted by avatar upload procedures |
TRUST_PROXY_HEADERS | Set to true only when a trusted edge appends the verified client IP to X-Forwarded-For and direct traffic cannot reach the app |
Copy .env.example as a starting point and supply real values for the selected providers. Missing credentials do not universally select mocks. Production payment/storage paths fail without configuration unless sandbox mode is explicitly enabled; mail and AI follow their documented selection rules.
Supported admin integration forms can save selected credentials in the database. They do not provide a generic credentials editor for every adapter. Check the provider-specific guide for environment keys and precedence. Secret fields saved by the integration forms are stored in SystemSetting encrypted at rest with APP_ENCRYPTION_KEY (AES-256-GCM); secret values are never returned to the browser. Environment-managed secrets stay environment-managed and read-only in the UI. Restrict database access, guard the encryption key separately from backups, and protect backups accordingly.
Never commit .env; variables prefixed NEXT_PUBLIC_ are browser-visible and are compiled into the browser bundle. Changing one requires a new production build and deployment; changing a runtime secret does not update an already-built public value.
Provider selection confirms configuration, not a live provider check. Readiness checks required configuration, database reachability, and applied migrations without probing paid providers. Test each enabled provider's real flow before launch.
TRUST_PROXY_HEADERS=true uses the last valid IP in X-Forwarded-For. Leave it unset for local development and any deployment where clients can bypass the edge or control the forwarded header. Invalid, missing, and untrusted values share the fallback rate-limit bucket.
See Email Providers, Stripe and Project Structure.