Skip to main content

Environment variables

Configure Convex, Nuxt, and Better Auth without mixing build-time and runtime concerns.

Better Convex Nuxt connects three environments: the Nuxt build, the deployed Nuxt server and browser, and the Convex deployment. Put each value in the environment that consumes it.

Nuxt variables

VariableRequiredPurpose
SITE_URLYes with authExact public Nuxt origin used by the same-origin proxy
NUXT_PUBLIC_CONVEX_URLYesPublic Convex deployment URL, usually ending in .convex.cloud
NUXT_PUBLIC_CONVEX_SITE_URLWith auth for local or custom domainsConvex HTTP Actions origin used by the same-origin auth proxy
BCN_AUTH_PROXY_IP_SECRETYes with authPrivate signature key shared only with the Convex environment
BCN_AUTH_TRUSTED_CLIENT_IP_HEADEROutside exact loopback developmentHeader that your host overwrites with exactly one client IP

The module also reads CONVEX_URL and CONVEX_SITE_URL while Nuxt config is evaluated. Prefer the NUXT_PUBLIC_* names in deployment environments: Nuxt can apply those native public runtime-config overrides after the image was built.

.env.local
SITE_URL=https://app.example.com
NUXT_PUBLIC_CONVEX_URL=https://example.convex.cloud
NUXT_PUBLIC_CONVEX_SITE_URL=https://example.convex.site
BCN_AUTH_PROXY_IP_SECRET=
BCN_AUTH_TRUSTED_CLIENT_IP_HEADER=

For local development, keep these values with the Convex CLI selection in the ignored .env.local that better-convex convex configure creates, and pass --dotenv .env.local to Nuxt commands. Do not add a sibling .env with a second copy. The endpoint values are public. BCN_AUTH_PROXY_IP_SECRET is not: generate it separately, set the same value in Nuxt and Convex, and leave the example blank until then so missing configuration stops auth requests. Do not place it in runtimeConfig.public, commit it, or expose it to browser code.

Convex variables for authentication

These values exist in the Convex deployment, not in the browser bundle:

VariableRequired with authPurpose
SITE_URLYesExact public Nuxt origin used as the Better Auth base and trusted origin
CONVEX_SITE_URLBuilt inDeployment-owned HTTP Actions origin used as the Convex session JWT issuer
BETTER_AUTH_SECRETSYesVersioned Better Auth encryption/signing secrets, newest version first
BCN_AUTH_PROXY_IP_SECRETYesSame separate proxy signature key used by the Nuxt server
bash
export BCN_AUTH_PROXY_IP_SECRET="$(openssl rand -base64 32)"
pnpm exec better-convex convex env set SITE_URL https://app.example.com
printf '1:%s' "$(openssl rand -base64 32)" | pnpm exec better-convex convex env set BETTER_AUTH_SECRETS
printf '%s' "$BCN_AUTH_PROXY_IP_SECRET" | pnpm exec better-convex convex env set BCN_AUTH_PROXY_IP_SECRET

Inject that same exported BCN_AUTH_PROXY_IP_SECRET into the Nuxt process with your secret manager, or start Nuxt from the same shell. Do not print or commit it. A blank Nuxt value deliberately fails closed.

Convex injects CONVEX_SITE_URL into functions as a deployment-owned built-in, and the CLI rejects attempts to override it. Do not shadow or manually provision it. Configure the matching public URL for Nuxt through NUXT_PUBLIC_CONVEX_SITE_URL.

SITE_URL must be an origin only: no path, query, or fragment. Use HTTPS outside loopback development. Configure separate values for preview and production deployments.

Every Convex command in these docs uses better-convex convex. This wrapper reads the target deployment only from .env.local. It rejects a file with more than one target, ignores CONVEX_* variables from the shell, and rejects target flags such as --prod. Before any production command, check that .env.local holds the production deploy key. See Deployment.

BETTER_AUTH_SECRET and AUTH_SECRET are rejected, not treated as aliases or decryption fallbacks; BETTER_AUTH_SECRETS is the sole accepted Better Auth secret setting.

Rotate BETTER_AUTH_SECRETS by adding a higher-numbered current value first, for example 2:new,1:old. Better Auth writes with the first version and retains the remaining versions for decryption. Do not reuse a Better Auth secret as the proxy signature key.

Build-time versus deploy-time

CONVEX_URL, SITE_URL, and BCN_AUTH_TRUSTED_CLIENT_IP_HEADER are read when nuxt.config.ts runs, so the build needs them. If a platform builds once and promotes the same artifact between environments, a later CONVEX_URL does not replace the baked public config. Use NUXT_PUBLIC_CONVEX_URL and NUXT_PUBLIC_CONVEX_SITE_URL as native deploy-time overrides, or rebuild for each environment.

The server limits accept the deploy-time overrides NUXT_PUBLIC_CONVEX_SERVER_MAX_RESPONSE_BYTES and NUXT_PUBLIC_CONVEX_SERVER_QUERY_TIMEOUT_MS. Each value must be a positive integer; an invalid value makes requests fail.

Auth identity is also environment-specific. A preview Nuxt origin must point to a Convex deployment whose SITE_URL matches that preview exactly. Do not share production cookies, secrets, or Convex data with previews.

Check before you deploy

Check all seven points:

  1. The browser can reach NUXT_PUBLIC_CONVEX_URL.
  2. The Nuxt server can reach both Convex origins.
  3. Nuxt and Convex have the same exact public origin in SITE_URL.
  4. Convex exposes its deployment-owned CONVEX_SITE_URL, and Nuxt targets that exact origin.
  5. BETTER_AUTH_SECRETS exists only in Convex and its secret manager.
  6. BCN_AUTH_PROXY_IP_SECRET matches in Nuxt and Convex but is absent from public config.
  7. Outside exact loopback development, BCN_AUTH_TRUSTED_CLIENT_IP_HEADER names a header that your host overwrites with exactly one client IP.

Continue with Deployment for the complete release checklist.