Bridge Training
Contributing

Environments

Environment variables required by each app, validation schemas, and file conventions.

Overview

Environment variables are validated at startup using t3-oss/env with Zod schemas. If a required variable is missing or malformed, the app fails immediately with a clear error.

Shared schemas (auth, stripe, supabase) are defined in their respective packages and composed into app-level schemas via the extends property.

Prefix conventions

FrameworkClient prefixExample
Vite (App, Editor, Player)VITE_VITE_SUPABASE_URL
Next.js (Web)NEXT_PUBLIC_NEXT_PUBLIC_BASE_URL
Server (API)(none)DATABASE_URL

Only prefixed variables are exposed to the browser. Server-side variables without a prefix stay on the server.

Build-time vs runtime

Variables behave differently depending on how the app is built:

  • Build-time (inlined): VITE_* and NEXT_PUBLIC_* variables are replaced with their values during the build step. They are baked into the JavaScript bundle and cannot be changed after build. This applies to all static apps (App, Editor, Player, Web).
  • Runtime (server): Variables without a prefix are read from the .env file when the server process starts. They can be changed by editing the file and restarting the container. This applies to Docker-based apps (API, Docs).

API (apps/api)

All variables are runtime — read from .env on the server when the container starts. The file must be created manually on the production server at /home/www/api/.env.

VariableRequiredPhaseDescription
DATABASE_URLYesRuntimePostgreSQL connection string
SUPABASE_URLYesRuntimeSupabase REST API URL
SUPABASE_SERVICE_ROLE_KEYYesRuntimeSupabase service role key (admin access)
CLERK_SECRET_KEYYesRuntimeClerk backend secret key
API_KEYYesRuntimeAPI key for service-to-service authentication
PORTNoRuntimeServer port (default: 3001)
CLERK_WEBHOOK_SECRETNoRuntimeClerk webhook signing secret — webhook routes disabled when not set
RESEND_API_KEYNoRuntimeResend API key — transactional emails disabled when not set

Template: apps/api/.env.local


App (apps/app)

All variables are build-time (VITE_ prefixed) — inlined into the bundle during pnpm build:app. Extends shared schemas from @workspace/auth, @workspace/stripe, and @workspace/database.

Core

VariableRequiredPhaseDescription
VITE_SUPABASE_URLYesBuildSupabase project URL
VITE_SUPABASE_ANON_KEYYesBuildSupabase anonymous (public) key
VITE_AUTH_PUBLISHABLE_KEYYesBuildClerk publishable key (starts with pk_)

App-specific

VariableRequiredPhaseDescription
VITE_USE_LOCAL_APINoBuildLocal API mode: "dev", "seed", or unset for remote
VITE_API_BASE_URLNoBuildAPI base URL override
VITE_FLAGSNoBuildFeature flags: comma-separated list or "*" for all
VITE_WEB_BASE_URLNoBuildMarketing site URL (default: https://bridge-training.com)
VITE_PLAYER_BASE_URLNoBuildDeal player URL
VITE_E2ENoBuildSet to "true" to enable E2E testing mode
VITE_SUPPORT_EMAILNoBuildSupport email displayed in UI
VariableRequiredPhaseDescription
VITE_STRIPE_DONATE_ONETIME_3NoBuildOne-time 3€ donation link
VITE_STRIPE_DONATE_ONETIME_5NoBuildOne-time 5€ donation link
VITE_STRIPE_DONATE_ONETIME_10NoBuildOne-time 10€ donation link
VITE_STRIPE_DONATE_ONETIME_20NoBuildOne-time 20€ donation link
VITE_STRIPE_DONATE_ONETIME_50NoBuildOne-time 50€ donation link
VITE_STRIPE_DONATE_ONETIME_CUSTOMNoBuildCustom amount donation link
VITE_STRIPE_DONATE_MONTHLY_2NoBuildMonthly 2€ donation link
VITE_STRIPE_DONATE_MONTHLY_5NoBuildMonthly 5€ donation link
VITE_STRIPE_DONATE_MONTHLY_10NoBuildMonthly 10€ donation link
VITE_STRIPE_DONATE_MONTHLY_15NoBuildMonthly 15€ donation link
VITE_STRIPE_BILLING_PORTAL_URLNoBuildStripe billing portal for subscription management

Template: apps/app/.env.example


Editor (apps/editor)

All variables are build-time (VITE_ prefixed) — inlined into the bundle during build.

VariableRequiredPhaseDescription
VITE_DEAL_GENERATION_ENDPOINTYesBuildURL for deal generation/shortening service
VITE_PLAYER_BASE_URLYesBuildBase URL for the deal player
VITE_SUPPORT_EMAILNoBuildSupport email (default: contact@bridge-training.com)

Template: apps/editor/.env.development


Web (apps/web)

All variables are build-time (NEXT_PUBLIC_ prefixed) — inlined during next build.

VariableRequiredPhaseDescription
NEXT_PUBLIC_BASE_URLNoBuildSite base URL for sitemap and OG tags
NEXT_PUBLIC_SIGN_IN_URLNoBuildSign-in page URL
NEXT_PUBLIC_SIGN_UP_URLNoBuildSign-up page URL
NEXT_PUBLIC_EDITOR_URLNoBuildEditor app URL
NEXT_PUBLIC_STRIPE_DONATE_ONETIME_*NoBuildSame Stripe links as App, with NEXT_PUBLIC_ prefix
NEXT_PUBLIC_STRIPE_DONATE_MONTHLY_*NoBuildSame Stripe links as App, with NEXT_PUBLIC_ prefix
NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URLNoBuildStripe billing portal

Template: apps/web/.env.example


Database (packages/database)

Used by Drizzle Kit and Supabase CLI for migrations and local development.

VariableRequiredPhaseDescription
DATABASE_URLYesRuntimePostgreSQL connection string
SUPABASE_WORKDIRNoRuntimeSupabase CLI working directory (default: ./supabase)
SUPABASE_PROJECT_ID_PRODNoRuntimeProduction project ID (for remote operations)
SUPABASE_DB_URL_PRODNoRuntimeProduction database URL (for remote migrations)

Template: packages/database/.env.local.example


CLI (packages/cli)

Internal CLI tool for admin operations.

VariableRequiredPhaseDescription
DATABASE_URLYesRuntimePostgreSQL connection string
CLERK_SECRET_KEYYesRuntimeClerk backend secret key

Template: packages/cli/.env.example


Deploy (/.env.deploy)

Used by release scripts only. See Deployment for details.

VariableRequiredPhaseDescription
API_HOSTYesDeploySSH host alias for API server
API_REMOTE_DIRYesDeployRemote directory for API deployment
API_PORTYesDeployAPI container exposed port
API_IMAGEYesDeployDocker image name for API
DOCS_HOSTYesDeploySSH host alias for Docs server
DOCS_REMOTE_DIRYesDeployRemote directory for Docs deployment
DOCS_PORTYesDeployDocs container exposed port
DOCS_IMAGEYesDeployDocker image name for Docs
API_URLNoDeployAPI URL (displayed after release)
DOCS_URLNoDeployDocs URL (displayed after release)

Override locally with .env.deploy.local (gitignored).


Validation schemas

Schemas are colocated with the packages that own the concern:

SchemaPackageUsed by
authEnvpackages/auth/src/env.tsApp
stripeEnvpackages/stripe/src/env.tsApp
stripeEnvNextjspackages/stripe/src/env-nextjs.tsWeb
supabaseEnvpackages/database/src/env.tsApp
API envapps/api/src/lib/env.tsAPI
Editor envapps/editor/src/lib/env.tsEditor
Web envapps/web/src/lib/env.tsWeb
App envapps/app/src/lib/env.tsApp

On this page