Addresses
The four values that decide where callbacks land, the two that must be random, and the extra names the app reads without the installer asking.
This page collects the settings that are not about a provider or a service: the addresses, the two secrets, and a small number of names the code reads that the guided walk does not ask about.
The two addresses, which have to agree
| Name | Read by | What it is used to build |
|---|---|---|
NEXT_PUBLIC_APP_URL | The app | Provider callbacks, the connect flow's return address, links |
SITE_URL | The deployment | Links inside emails, and the base the sessions are built on |
On a laptop both are http://localhost:3000. On a server both are the address people actually visit,
including the scheme: https://loomis.your-domain.com.
The address that half worked
Setting one and not the other produces the confusing pair of symptoms: sign in
with a password works, and every email link points at localhost. Both are
the same mistake, and both are fixed by setting the other name.
Three things must match the address, and the manual says so on each of their pages:
- The authorized redirect URIs in Google's console.
- The authorization callback URL in GitHub's OAuth app.
- The reverse proxy and certificate on the host, which must serve that address over TLS.
The two secrets
Both are long random strings, and both are read where the thing they protect happens.
openssl rand -base64 32 # run it twice, once for each| Name | Home | What it protects | Cost of rotating |
|---|---|---|---|
SETTINGS_SECRET | The app | Every sealed token: integrations, provider keys, webhook secrets | Stored values become unreadable. Reconnect and re-paste |
BETTER_AUTH_SECRET | The deployment | Session tokens | Everybody is signed out and signs in again |
A secret in a document is not a secret
These belong in .env.local and in the deployment's environment. They do not
belong in an email to your developer, in a screenshot of the panel, or in a
support ticket. The panel shows whether a name is set and never shows the
value, which is the behaviour to expect everywhere.
Names the app reads that the walk does not ask for
The nineteen in the catalogue are the ones every installation needs to think about. The code reads a few more, each with a sensible fallback, and they are listed here so that nothing about the configuration is hidden.
| Name | Default when unset | What it does |
|---|---|---|
NEXT_PUBLIC_CONVEX_SITE_URL | NEXT_PUBLIC_APP_URL, then localhost | The address the authentication routes are forwarded to. Set it explicitly only if the deployment's site URL differs from your app's address |
CONVEX_DEPLOY_KEY | none | A production deploy key, for a machine that pushes to Convex without signing in. Used by npx convex deploy in CI, never at runtime |
CONVEX_DEPLOYMENT | written by npx convex dev | Which deployment the CLI talks to in this folder. Managed by the CLI, not by you |
A deploy key is not an environment name
CONVEX_DEPLOY_KEY is read by the Convex command line, not by the app or the
deployment at runtime. Putting it in the deployment's environment does
nothing, and putting it in .env.local only helps a script that runs npx convex deploy on that machine.
The optional two, in one place
| Name | Optional because | Where the panel version lives |
|---|---|---|
ALLOW_SELF_UPDATE | Most hosts should update deliberately, from a shell they control | System → Setup & licensing |
CREDIT_MONTHLY_CAP | The Credits screen has its own ceiling, and a shipped default | Money → Credits |
Both are counted separately from the seventeen that matter, so an unset one never reads as a fault.
A checklist before you call it done
Both addresses are the real one
NEXT_PUBLIC_APP_URL and SITE_URL say the address people visit, with the right scheme and no trailing
slash.
Both secrets are yours
Neither is the value that shipped, and neither appears anywhere in your notes.
Every provider that is switched on agrees
The Google console, the GitHub applications and the values in the deployment name the address from step one.
The panel agrees
Platform → Environment shows Set beside everything that should be set and Not set only beside the
two optional names, or beside a feature you decided to leave for later.
Health is green
System → Status & health answers for the app, the backend, the gateway and the mail provider, with the
time each took.

