Brisket Environment Variables
Brisket validates env vars with @t3-oss/env-nextjs in apps/brisket/src/env.js. Variables fall into two pools:
server— accessible only in Node runtime (route handlers, server components, tRPC procedures, middleware). Never bundled into client JS.client— must be prefixedNEXT_PUBLIC_; values are inlined into the browser bundle at build time. Treat all values as public.
Empty strings are coerced to undefined (emptyStringAsUndefined: true). Set SKIP_ENV_VALIDATION=1 to bypass validation in Docker builds. Reference: apps/brisket/.env.example.
Exposure Boundary
flowchart LR subgraph Server[Node runtime — server-only] S1[CLERK_SECRET_KEY] S2[CHARGE_BEE_API_KEY] S3[STRAPI_TOKEN] S4[CF_TURNSTILE_SECRET_KEY] S5[INTERCOM_API_TOKEN] S6[SIRLOIN_URL] end subgraph Client[Browser bundle — public] C1[NEXT_PUBLIC_*] endAnything required by the client: schema in env.js is shipped to every visitor. Anything in server: stays in the Node process. Crossing the boundary the wrong way (e.g. importing env.CLERK_SECRET_KEY in a client component) will fail the build.
Server Variables
| Variable | Required | Default | Source | Purpose |
|---|---|---|---|---|
CLERK_SECRET_KEY | yes | – | Clerk dashboard | Auth backend secret used by @clerk/nextjs/server and middleware. |
CLERK_WEBHOOK_SECRET | yes | – | Clerk dashboard → webhooks | Verifies Svix signatures on /api/webhook/clerk. |
NODE_ENV | yes | development | runtime | Standard Node env. |
BRISKET_STAGE | yes | development | deploy config / RAILWAY_ENVIRONMENT_NAME fallback | One of production | staging | sandbox | development. Resolved via resolveBrisketStageInput in src/stage.js. Drives feature gating and logging. |
SIRLOIN_URL | yes | – | service discovery | gRPC base URL for sirloin (server/api/sirloin-api.ts). |
FACEBOOK_ACCESS_TOKEN | yes | – | Meta Business | Server-side conversions API for ad attribution. |
CHARGE_BEE_API_KEY | yes | – | Chargebee | Server-side Chargebee REST calls. |
CHARGE_BEE_PAYPAL_PRO_GATEWAY | yes | – | Chargebee | PayPal Pro gateway selector for billing. |
STRAPI_URL | yes | – | chuck deploy | Headless CMS base URL (FAQ, marketing). |
STRAPI_TOKEN | yes | – | chuck admin | Bearer token for Strapi reads. |
CF_TURNSTILE_SECRET_KEY | optional | – | Cloudflare Turnstile | Server-side validation of Turnstile tokens during checkout. |
INTERCOM_API_TOKEN | optional | – | Intercom | Used by intercom tRPC router; soft-failure if unset. |
OTel exporters use BRISKET_OTEL_URL, BRISKET_OTEL_METRICS_HEADERS, BRISKET_OTEL_TRACES_LOGS_HEADERS from .env.example. Not validated by env.js — consumed directly in the OTel bootstrap at apps/brisket/otel.server.config.ts (trace/metric/log exporter URLs and headers) and gated by apps/brisket/src/otel-runtime-config.ts (shouldEnableMetrics / shouldEnableTraces only enable the SDK if both URL and the corresponding header are non-empty).
Client Variables (NEXT_PUBLIC_*)
All values below are baked into the client bundle. Do not store secrets here.
| Variable | Required | Default | Source | Purpose |
|---|---|---|---|---|
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | yes | – | Clerk | Browser-side Clerk SDK init. |
NEXT_PUBLIC_CLERK_SIGN_IN_URL | yes | /sign-in | static | Clerk redirect target. |
NEXT_PUBLIC_CLERK_SIGN_UP_URL | yes | /sign-up | static | Clerk redirect target. |
NEXT_PUBLIC_POSTHOG_KEY | yes | – | PostHog project | Browser PostHog init. |
NEXT_PUBLIC_POSTHOG_HOST | yes | – | PostHog | EU/US ingest host. |
NEXT_PUBLIC_CHARGE_BEE_SITE | yes | – | Chargebee | Site slug for Chargebee.js. |
NEXT_PUBLIC_CHARGE_BEE_PUBLISHABLE_KEY | yes | – | Chargebee | Publishable key for Chargebee.js. |
NEXT_PUBLIC_APP_URL | optional | – | deploy | Canonical app origin (used in metadata, redirects). |
NEXT_PUBLIC_FACEBOOK_PIXEL_ID | yes | – | Meta | Pixel ID for client tracking. |
NEXT_PUBLIC_DEV_FEATURES | optional | – | local / staging | Toggles dev-only UI surfaces ("true"). |
NEXT_PUBLIC_FORCE_DEV_KLAVIYO | optional | – | local | Forces Klaviyo to run in dev. |
NEXT_PUBLIC_CF_TURNSTILE_SITE_KEY | optional | – | Cloudflare | Public Turnstile site key for the checkout widget. |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | optional | – | Stripe | Stripe.js init when Stripe gateway is active. |
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY | optional | – | GCP | Maps JS for billing-address autocomplete. |
NEXT_PUBLIC_KLAVIYO_PUBLIC_KEY | optional | – | Klaviyo | Klaviyo browser SDK. Not in env.js schema; consumed directly via process.env in apps/brisket/src/features/analytics/klaviyo/klaviyo-tracking-script/index.tsx (script src + early-exit when blank). Pair with NEXT_PUBLIC_FORCE_DEV_KLAVIYO=true to enable in dev. |
Stage Resolution
BRISKET_STAGE is resolved by resolveBrisketStageInput(BRISKET_STAGE, RAILWAY_ENVIRONMENT_NAME, NODE_ENV) in apps/brisket/src/stage.js. Railway environments map to stages so deployments don’t need to set BRISKET_STAGE explicitly.
Local Setup
Copy .env.example to .env.local and fill in dev credentials. The 1Password vault holds the canonical dev values — TODO(@marty): vault item name. Run pnpm --filter brisket dev after env is in place; missing required vars will fail at startup with a Zod aggregate error.