Environment Variables
Complete reference for configuring Quickback Account UI
Environment Variables
Configure the Account UI by setting environment variables in your .env file or deployment platform.
Runtime config takes precedence
Every variable on this page can also be delivered at serve time via the worker-injected window.__QUICKBACK_RUNTIME blob. When a Quickback-generated worker serves the Account UI (unified /account, custom domain, or dev hostnames), it injects the project's values into the HTML shell automatically. Resolution precedence for every per-project field is:
window.__QUICKBACK_RUNTIME.<field>(injected by the serving worker)- Baked
VITE_*env (this page — set at build time) - Built-in default
This means a single generic build of the Account UI (no .env) behaves identically to a per-project baked build when served by the worker. Baked builds keep working unchanged — the blob simply wins when both are present.
Quick Setup — Single Variable
For the common "unified deployment" where API, Account, and CMS all live on the same Quickback origin, you only need one variable:
# Points at the Quickback Worker origin
VITE_QUICKBACK_URL=https://secure.example.comWhen VITE_QUICKBACK_URL is set, it's used as a fallback for the individual URL vars:
| Individual var | Used first | Falls back to |
|---|---|---|
VITE_QUICKBACK_API_URL | if set | ${VITE_QUICKBACK_URL} |
VITE_QUICKBACK_ACCOUNT_URL | if set | ${VITE_QUICKBACK_URL}/account |
VITE_QUICKBACK_CMS_URL | if set | ${VITE_QUICKBACK_URL}/cms |
VITE_QUICKBACK_APP_URL is independent
VITE_QUICKBACK_APP_URL points at the tenant's own frontend (where users are redirected after login). It's not derived from VITE_QUICKBACK_URL — set it separately if needed.
Required Variables
At minimum, you need one of:
VITE_QUICKBACK_URL— catch-all for the Quickback origin (recommended), orVITE_QUICKBACK_API_URL— explicit API URL (use this if your API lives on a different subdomain from Account/CMS)
Split-subdomain setup
If your API, Account, and CMS live on separate custom subdomains, set them explicitly:
# Quickback API URL
VITE_QUICKBACK_API_URL=https://api.example.com
# Account UI URL (where the Account UI is deployed)
VITE_ACCOUNT_APP_URL=https://account.example.com
# Optional: override Account/CMS URLs for cross-origin links
VITE_QUICKBACK_ACCOUNT_URL=https://auth.example.com
VITE_QUICKBACK_CMS_URL=https://cms.example.comThe fallback is same-origin, not an error
If neither VITE_QUICKBACK_URL nor VITE_QUICKBACK_API_URL resolves (and the worker injected no apiUrl), the API base falls back to window.location.origin. Nothing throws — the SPA just talks to whatever host served it. That is exactly right on a unified deployment and silently wrong when the API lives elsewhere, so set one of them explicitly for split-subdomain setups.
App Identity
Configure your application's basic information:
# App name (displayed in UI)
VITE_APP_NAME=My Application
# Tagline (shown on landing pages)
VITE_APP_TAGLINE=Build faster, ship sooner
# Full description
VITE_APP_DESCRIPTION=A complete platform for building modern web applications
# Company information
VITE_COMPANY_NAME=My Company Inc.
VITE_COMPANY_ADDRESS=123 Main St, Suite 100, San Francisco, CA 94105URLs
Main Application
# Your main application URL
# Users will be redirected here after authentication
VITE_QUICKBACK_APP_URL=https://app.example.com
# Organization/Tenant URL pattern (optional)
# Use {slug} as placeholder for organization identifier
# Examples:
# /organizations/{slug} -> app.example.com/organizations/acme
# /workspace/{slug} -> app.example.com/workspace/acme
# https://{slug}.example.com -> acme.example.com
VITE_TENANT_URL_PATTERN=/organizations/{slug}Support and Legal
# Support/help URL
VITE_SUPPORT_URL=https://support.example.com
# Privacy policy URL
VITE_PRIVACY_URL=https://example.com/privacy
# Terms of service URL
VITE_TERMS_URL=https://example.com/termsEmail Configuration
# From address for all emails
VITE_EMAIL_FROM=noreply@example.com
# Reply-to address
VITE_EMAIL_REPLY_TO=support@example.com
# Support email address
VITE_SUPPORT_EMAIL=support@example.com
# AWS Region for SES (if using AWS SES)
VITE_EMAIL_REGION=us-east-1Branding
# Primary theme color (hex code)
VITE_THEME_COLOR=#1e293b
# SEO keywords (comma-separated)
VITE_SEO_KEYWORDS=saas,authentication,account managementFeature Flags
Enable or disable features using boolean environment variables. Every flag carries the VITE_ prefix — Vite only exposes VITE_* vars to client code, so an unprefixed ENABLE_PASSKEY=true is read by nothing.
appConfig.features
| Variable | features key | Default |
|---|---|---|
VITE_ENABLE_ORGANIZATIONS | organizations | false |
VITE_ENABLE_ORG_TEAMS | orgTeams | false |
VITE_ENABLE_ADMIN | admin | true |
VITE_ENABLE_FILE_UPLOADS | fileUploads | false |
VITE_ENABLE_PASSKEY | passkey | false |
VITE_ENABLE_EMAIL_OTP | emailOTP | false |
VITE_ENABLE_PASSWORD | password | true |
VITE_ENABLE_GOOGLE_OAUTH | googleOAuth | false |
VITE_ENABLE_SUBSCRIPTIONS | subscriptions | false |
VITE_ENABLE_REALTIME | realtime | false |
appConfig.auth
| Variable | auth key | Default |
|---|---|---|
VITE_ENABLE_SIGNUP | enableSignup | true |
VITE_ENABLE_EMAIL_VERIFICATION | requireEmailVerification | true |
VITE_DISABLE_EMAIL_STATUS_CHECK | disableEmailStatusCheck | false |
Password is on, passkey and OTP are off
The out-of-the-box posture is email + password only. Passkey, email OTP, organizations, Google OAuth, subscriptions, and realtime all default to false. Admin defaults to true.
These are the SPA's built-in defaults. In a compiled project the compiler derives the flags from your Better Auth config and account.auth shorthand, and only emits a VITE_* value when it has one — notably organizations resolves to true unless you opt out. See Feature Flags for the derivations that differ.
# Authentication
VITE_ENABLE_SIGNUP=true # default: true
VITE_ENABLE_EMAIL_VERIFICATION=true # default: true
VITE_DISABLE_EMAIL_STATUS_CHECK=false # default: false — inverted sense
VITE_ENABLE_PASSWORD=true # default: true
VITE_ENABLE_PASSKEY=false # default: false
VITE_ENABLE_EMAIL_OTP=false # default: false
VITE_ENABLE_GOOGLE_OAUTH=false # default: false
# Account management
VITE_ENABLE_FILE_UPLOADS=false # default: false
VITE_ENABLE_SUBSCRIPTIONS=false # default: false
VITE_ENABLE_REALTIME=false # default: false
# Organizations
VITE_ENABLE_ORGANIZATIONS=false # default: false
VITE_ENABLE_ORG_TEAMS=false # default: false
# Auto-set to true when the BA config has organization({ teams: { enabled: true } }).
# When false the Teams tab is hidden and the auth client doesn't expose team APIs.
# Admin
VITE_ENABLE_ADMIN=true # default: truePer-flag behaviour is documented under Feature Flags.
Complete Example
Here's a complete .env file with all common configuration:
# ===== REQUIRED =====
VITE_QUICKBACK_API_URL=https://api.example.com
VITE_ACCOUNT_APP_URL=https://account.example.com
# ===== APP IDENTITY =====
VITE_APP_NAME=Acme SaaS
VITE_APP_TAGLINE=Build faster, ship sooner
VITE_APP_DESCRIPTION=The complete platform for modern web applications
VITE_COMPANY_NAME=Acme Corporation
VITE_COMPANY_ADDRESS=123 Main St, Suite 100, San Francisco, CA 94105
# ===== URLS =====
VITE_QUICKBACK_APP_URL=https://app.acme.com
VITE_TENANT_URL_PATTERN=/organizations/{slug}
VITE_SUPPORT_URL=https://help.acme.com
VITE_PRIVACY_URL=https://acme.com/privacy
VITE_TERMS_URL=https://acme.com/terms
# ===== EMAIL =====
VITE_EMAIL_FROM=noreply@acme.com
VITE_EMAIL_REPLY_TO=support@acme.com
VITE_SUPPORT_EMAIL=support@acme.com
VITE_EMAIL_REGION=us-east-1
# ===== BRANDING =====
VITE_THEME_COLOR=#3b82f6
# ===== SEO =====
VITE_SEO_KEYWORDS=saas,project management,team collaboration
# ===== FEATURES =====
VITE_ENABLE_SIGNUP=true
VITE_ENABLE_EMAIL_VERIFICATION=true
VITE_ENABLE_PASSKEY=true
VITE_ENABLE_EMAIL_OTP=true
VITE_ENABLE_PASSWORD=false
VITE_ENABLE_ORGANIZATIONS=true
VITE_ENABLE_ORG_TEAMS=true
VITE_ENABLE_ADMIN=true
VITE_ENABLE_FILE_UPLOADS=true
VITE_VITE_DISABLE_EMAIL_STATUS_CHECK=falseEnvironment-Specific Configuration
Development
VITE_QUICKBACK_API_URL=http://localhost:8787
VITE_ACCOUNT_APP_URL=http://localhost:5173
VITE_QUICKBACK_APP_URL=http://localhost:3000
VITE_DISABLE_EMAIL_STATUS_CHECK=trueStaging
VITE_QUICKBACK_API_URL=https://api-staging.example.com
VITE_ACCOUNT_APP_URL=https://account-staging.example.com
VITE_QUICKBACK_APP_URL=https://app-staging.example.comProduction
VITE_QUICKBACK_API_URL=https://api.example.com
VITE_ACCOUNT_APP_URL=https://account.example.com
VITE_QUICKBACK_APP_URL=https://app.example.com
VITE_DISABLE_EMAIL_STATUS_CHECK=falseDeployment
The Account UI has no standalone deploy path — the compiler builds it from source and bundles it into your Worker. In a compiled project you normally set none of the variables on this page by hand:
- Declare the values in
quickback.config.tsunderaccount(name, branding, URLs,authfeature flags). quickback compilewrites the matching.envfor the in-Docker Vite build and bakes the same values into the generated worker.- The worker injects them into every served Account shell as
window.__QUICKBACK_RUNTIME, which the SPA prefers over the bakedVITE_*values.
quickback compile
npx wrangler deploySee With Quickback for the full pipeline.
`VITE_*` vars are not worker vars
Do not put VITE_* entries in wrangler.toml [vars] or .dev.vars. Those are Worker runtime bindings; Vite reads its env at build time and the runtime blob is baked into the worker source at compile time. Neither one consults [vars].
The .env files documented above apply when you run the Account SPA outside a Quickback worker — local vite dev against a remote API, or hosting the built assets yourself. In that case the values are baked at build time and changing one requires a rebuild.
Runtime Configuration
Some values can be overridden at runtime using the config API:
import { setAppConfig } from '@/config/app';
setAppConfig({
name: 'My Custom App',
branding: {
primaryColor: '#ff6600',
logoUrl: '/custom-logo.png',
},
urls: {
base: 'https://account.custom.com',
app: 'https://app.custom.com',
},
});Limitations
Runtime configuration only works for values consumed by the React application. Environment variables used during the Vite build process cannot be changed at runtime.
Resolution behaviour
Config resolution is lenient — there is no startup validation pass and no throw for a missing URL:
- No API URL resolved — falls back to
window.location.origin - No
VITE_QUICKBACK_ACCOUNT_URL/VITE_QUICKBACK_CMS_URL— derived fromVITE_QUICKBACK_URLas${base}/accountand${base}/cms;nullif that is unset too - Missing optional fields — use the built-in defaults listed above
The two calls that do throw are getDataApiUrl() and getStorageApiUrl(), when authRoute is not "quickback" and routes.api.data / routes.api.storage were never configured.
Next Steps
- Feature Flags - Detailed feature configuration
- Customization - Customize labels and messages
- With Quickback - How the compiler builds and bundles Account UI