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
| Variable | Required | Purpose |
|---|---|---|
SITE_URL | Yes with auth | Exact public Nuxt origin used by the same-origin proxy |
NUXT_PUBLIC_CONVEX_URL | Yes | Public Convex deployment URL, usually ending in .convex.cloud |
NUXT_PUBLIC_CONVEX_SITE_URL | With auth for local or custom domains | Convex HTTP Actions origin used by the same-origin auth proxy |
BCN_AUTH_PROXY_IP_SECRET | Yes with auth | Private signature key shared only with the Convex environment |
BCN_AUTH_TRUSTED_CLIENT_IP_HEADER | Outside exact loopback development | Ingress-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.
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:
| Variable | Required with auth | Purpose |
|---|---|---|
SITE_URL | Yes | Exact public Nuxt origin used as the Better Auth base and trusted origin |
CONVEX_SITE_URL | Built in | Deployment-owned HTTP Actions origin used as the Convex session JWT issuer |
BETTER_AUTH_SECRETS | Yes | Versioned Better Auth encryption/signing secrets, newest version first |
BCN_AUTH_PROXY_IP_SECRET | Yes | Same separate proxy signature key used by the Nuxt server |
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_SECRETInject 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:
- The browser can reach
NUXT_PUBLIC_CONVEX_URL. - The Nuxt server can reach both Convex origins.
- Nuxt and Convex have the same exact public origin in
SITE_URL. - Convex exposes its deployment-owned
CONVEX_SITE_URL, and Nuxt targets that exact origin. BETTER_AUTH_SECRETSexists only in Convex and its secret manager.BCN_AUTH_PROXY_IP_SECRETmatches in Nuxt and Convex but is absent from public config.- Outside exact loopback development,
BCN_AUTH_TRUSTED_CLIENT_IP_HEADERnames a header that the ingress overwrites with exactly one client IP.
Continue with Deployment for the complete release checklist.