Owner: Engineering Team | Last Updated: 2026-01-30 | Status: Current
The WWAI web app uses 36 environment variables — 23 browser-accessible (NEXT_PUBLIC_*) and 13 server-only. The most critical is NEXT_PUBLIC_BACKEND_URL which appears 40+ times in the codebase.
Warning: Variables prefixed with NEXT_PUBLIC_ are bundled into client-side JavaScript and visible to users. Never include secrets, API keys, or passwords in NEXT_PUBLIC_ variables.
These are bundled into the client-side JavaScript and visible to users. Never put secrets here.
| Variable |
Required |
Description |
NEXT_PUBLIC_BACKEND_URL |
Yes |
Django backend API base URL (e.g., https://api.wwai.com) |
NEXT_PUBLIC_ENVIRONMENT |
Yes |
Environment identifier: production, development, or local |
NEXT_PUBLIC_WALTER_STATIC_URL |
No |
Static website URL for terms, privacy, refund policy links |
Naming pattern: NEXT_PUBLIC_WALTER_{PLAN}_{PERIOD} for Stripe price IDs and _PRICE suffix for display amounts.
| Variable |
Description |
NEXT_PUBLIC_WALTER_STARTER_M |
Starter monthly — Stripe Price ID |
NEXT_PUBLIC_WALTER_STARTER_M_PRICE |
Starter monthly — display price (e.g., "12.99") |
NEXT_PUBLIC_WALTER_STARTER_Y |
Starter yearly — Stripe Price ID |
NEXT_PUBLIC_WALTER_STARTER_Y_PRICE |
Starter yearly — display price |
NEXT_PUBLIC_WALTER_PRO_M |
Pro monthly — Stripe Price ID |
NEXT_PUBLIC_WALTER_PRO_M_PRICE |
Pro monthly — display price |
NEXT_PUBLIC_WALTER_PRO_Y |
Pro yearly — Stripe Price ID |
NEXT_PUBLIC_WALTER_PRO_Y_PRICE |
Pro yearly — display price |
NEXT_PUBLIC_WALTER_UNLIMITED_M |
Unlimited monthly — Stripe Price ID |
NEXT_PUBLIC_WALTER_UNLIMITED_M_PRICE |
Unlimited monthly — display price |
NEXT_PUBLIC_WALTER_UNLIMITED_Y |
Unlimited yearly — Stripe Price ID |
NEXT_PUBLIC_WALTER_UNLIMITED_Y_PRICE |
Unlimited yearly — display price |
| Variable |
Required |
Description |
NEXT_PUBLIC_SENTRY_DSN |
Yes (prod) |
Sentry error tracking Data Source Name |
NEXT_PUBLIC_SENTRY_PROJECT |
Yes (prod) |
Sentry project name |
NEXT_PUBLIC_SENTRY_URL |
Yes (prod) |
Sentry server URL |
NEXT_PUBLIC_GTM_ID |
No |
Google Tag Manager container ID |
NEXT_PUBLIC_CLARITY_ID |
No |
Microsoft Clarity analytics ID |
NEXT_PUBLIC_CRISP_SECRET_KEY |
No |
Crisp chat/messaging secret key |
| Variable |
Required |
Description |
NEXT_PUBLIC_TURNSTILE_SITE_KEY |
Yes (prod) |
Cloudflare Turnstile captcha site key |
| Variable |
Required |
Description |
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA |
No |
Auto-set by Vercel — git commit hash |
These are never exposed to the browser. They contain secrets and API keys.
| Variable |
Required |
Description |
NEXTAUTH_SECRET |
Yes |
NextAuth.js session encryption secret |
NEXTAUTH_URL |
Yes |
NextAuth base URL (e.g., https://app.wwai.com) |
GOOGLE_CLIENT_ID |
Yes (if OAuth) |
Google OAuth client ID |
GOOGLE_CLIENT_SECRET |
Yes (if OAuth) |
Google OAuth client secret |
FACEBOOK_CLIENT_ID |
Yes (if OAuth) |
Facebook OAuth client ID |
FACEBOOK_CLIENT_SECRET |
Yes (if OAuth) |
Facebook OAuth client secret |
| Variable |
Required |
Description |
WALTER_INTERNAL_KEY |
Yes |
Internal API key sent as X-Walter-Internal-Key header on all utils/api.ts requests |
IP_API_KEY |
No |
API key for IP geolocation service (ipapi.co) |
| Variable |
Required |
Description |
CHURNKEY_LIVE_KEY |
Yes (prod) |
Churnkey production API key (churn recovery) |
CHURNKEY_TEST_KEY |
No |
Churnkey test/sandbox API key |
SENTRY_AUTH_TOKEN |
Yes (prod) |
Sentry auth token for source map uploads |
| Variable |
Required |
Description |
NODE_ENV |
Auto |
Node.js environment (production, development) |
CI |
Auto |
Set by CI/CD pipelines (GitHub Actions) |
NEXT_RUNTIME |
Auto |
Next.js runtime detection (nodejs, edge) |
To run the web app locally, you need at minimum:
# .env.local (minimum)
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000
NEXT_PUBLIC_ENVIRONMENT=local
NEXTAUTH_SECRET=any-random-string-for-dev
NEXTAUTH_URL=http://localhost:3000
WALTER_INTERNAL_KEY=your-internal-key
Optional but recommended for full functionality:
# OAuth (needed for Google/Facebook login)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# Captcha (needed for registration)
NEXT_PUBLIC_TURNSTILE_SITE_KEY=your-turnstile-key
# Stripe (needed for payment flows)
NEXT_PUBLIC_WALTER_STARTER_M=price_xxx
NEXT_PUBLIC_WALTER_STARTER_M_PRICE=12.99
# ... (all pricing vars)
| Scenario |
Behavior |
Missing NEXT_PUBLIC_* var |
Compiles as undefined — no build error, but runtime failures |
| Missing server-only var |
Runtime error when the code path is executed |
Missing NEXTAUTH_SECRET |
NextAuth fails to initialize — login broken |
Missing NEXT_PUBLIC_BACKEND_URL |
All API calls fail — app non-functional |
| Missing OAuth vars |
OAuth buttons show but fail on click |
| Missing Stripe pricing vars |
Payment page shows broken prices |
| Date |
Author |
Change |
| 2026-01-30 |
Admin |
Initial creation |
| 2026-01-30 |
Docs team |
Rewritten with real code: all 36 vars categorized (23 browser + 13 server), pricing var naming pattern, minimum .env.local template, build vs runtime behavior |
Prev: Web App - API Integration | Next: Web App - Deployment | Up: WalterWrites