Quickback Docs

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:

  1. window.__QUICKBACK_RUNTIME.<field> (injected by the serving worker)
  2. Baked VITE_* env (this page — set at build time)
  3. 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.com

When VITE_QUICKBACK_URL is set, it's used as a fallback for the individual URL vars:

Individual varUsed firstFalls back to
VITE_QUICKBACK_API_URLif set${VITE_QUICKBACK_URL}
VITE_QUICKBACK_ACCOUNT_URLif set${VITE_QUICKBACK_URL}/account
VITE_QUICKBACK_CMS_URLif 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), or
  • VITE_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.com

The 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 94105

URLs

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/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/terms

Email 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-1

Branding

# Primary theme color (hex code)
VITE_THEME_COLOR=#1e293b

# SEO keywords (comma-separated)
VITE_SEO_KEYWORDS=saas,authentication,account management

Feature 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

Variablefeatures keyDefault
VITE_ENABLE_ORGANIZATIONSorganizationsfalse
VITE_ENABLE_ORG_TEAMSorgTeamsfalse
VITE_ENABLE_ADMINadmintrue
VITE_ENABLE_FILE_UPLOADSfileUploadsfalse
VITE_ENABLE_PASSKEYpasskeyfalse
VITE_ENABLE_EMAIL_OTPemailOTPfalse
VITE_ENABLE_PASSWORDpasswordtrue
VITE_ENABLE_GOOGLE_OAUTHgoogleOAuthfalse
VITE_ENABLE_SUBSCRIPTIONSsubscriptionsfalse
VITE_ENABLE_REALTIMErealtimefalse

appConfig.auth

Variableauth keyDefault
VITE_ENABLE_SIGNUPenableSignuptrue
VITE_ENABLE_EMAIL_VERIFICATIONrequireEmailVerificationtrue
VITE_DISABLE_EMAIL_STATUS_CHECKdisableEmailStatusCheckfalse

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: true

Per-flag behaviour is documented under Feature Flags.

Complete Example

Here's a complete .env file with all common configuration:

.env
# ===== 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=false

Environment-Specific Configuration

Development

.env.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=true

Staging

.env.staging
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.com

Production

.env.production
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=false

Deployment

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:

  1. Declare the values in quickback.config.ts under account (name, branding, URLs, auth feature flags).
  2. quickback compile writes the matching .env for the in-Docker Vite build and bakes the same values into the generated worker.
  3. The worker injects them into every served Account shell as window.__QUICKBACK_RUNTIME, which the SPA prefers over the baked VITE_* values.
quickback compile
npx wrangler deploy

See 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 from VITE_QUICKBACK_URL as ${base}/account and ${base}/cms; null if 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

On this page