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 developmentIngress-owned header containing 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-nuxt-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 fails closed. 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-nuxt-convex env set SITE_URL https://app.example.com
printf '1:%s' "$(openssl rand -base64 32)" | pnpm exec better-convex-nuxt-convex env set BETTER_AUTH_SECRETS
printf '%s' "$BCN_AUTH_PROXY_IP_SECRET" | pnpm exec better-convex-nuxt-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 supported Convex CLI command in this guide uses better-convex-nuxt-convex. The checked runner reads only .env.local for its deployment selection, rejects hidden or conflicting authority, strips inherited CONVEX_* values, and rejects command-line target overrides before starting the pinned Convex CLI. Before any production command, inspect the file and verify its deployment-scoped key against the intended release target.

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 is read when nuxt.config.ts runs. 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.

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.

Verify before deployment

Check all seven boundaries:

  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 the ingress overwrites with exactly one client IP.

Continue with Deployment for the complete release checklist.