Environment variables
Copy .env.example to .env at the repo root and fill it in. .env is gitignored.
Supabase keys use the new format (sb_publishable_…, sb_secret_…).
When you add a variable, update this page and .env.example in the same change.
App and local development
Section titled “App and local development”| Variable | Read by | Purpose |
|---|---|---|
VITE_SUPABASE_URL |
Browser and server | The Supabase project URL. Locally, the shared dev project. |
VITE_SUPABASE_PUBLISHABLE_KEY |
Browser and server | Publishable key. Safe in the browser. |
SUPABASE_SECRET_KEY |
Server only | Secret key for the service-role client. Never sent to the browser. |
SITE_URL |
Server | Base URL for auth redirect links and invitation links. |
VITE_DOCS_URL |
Browser | This site’s URL, for the Docs link in the app’s top bar. Hidden when unset. |
RESEND_API_KEY |
Server, configure script | Optional. Sends invitation emails through Resend, and lets the configure script set Resend up as Supabase’s SMTP. |
SMTP_SENDER_EMAIL |
Server, configure script | Needed with RESEND_API_KEY. A sending address on a domain verified in Resend. |
SMTP_SENDER_NAME |
Server, configure script | Optional display name. Defaults to “Movement Mapping Tool”. Quote it if it has spaces. |
MAINTENANCE_PURGE_SECRET |
Server, purge cron | The shared secret for POST /api/maintenance/purge (header x-maintenance-secret). Set the same value on the prod app and the cron. |
SUPABASE_ACCESS_TOKEN |
scripts/supa, configure script, CI |
Your personal Supabase access token. |
SUPABASE_PROJECT_REF |
scripts/supa, first-run and configure scripts |
The project ref: the subdomain of VITE_SUPABASE_URL. |
SUPABASE_DB_PASSWORD |
scripts/supa |
The project’s database password, for linking. |
VITE_* values are built into the app’s JavaScript at build time. After changing one in
Render, redeploy the service.
Without the Resend variables, invitations are still created, but no email is sent.
Set by tools, not by you
Section titled “Set by tools, not by you”| Variable | Set by | Purpose |
|---|---|---|
SUPABASE_BRANCH_REF, VITE_SUPABASE_BRANCH_REF |
scripts/supa |
Routes requests to a Supabase branch with the x-supabase-branch header. Always unset while branching is disabled. |
SUPABASE_FIRST_RUN |
scripts/supa-first-run.sh |
Marks a first-run migration. Has no effect while the protected-branch guard in scripts/supa is disabled. |
IS_PULL_REQUEST, RENDER_EXTERNAL_URL |
Render | On a PR preview, invitation links use RENDER_EXTERNAL_URL instead of SITE_URL. |
NODE_VERSION |
render.yaml |
Node version for Render builds (22). |
CI and deployment secrets
Section titled “CI and deployment secrets”These live in GitHub, not in anyone’s .env:
| Secret | Purpose |
|---|---|
SUPABASE_ACCESS_TOKEN |
Applies migrations. |
SUPABASE_DEV_PROJECT_REF, SUPABASE_DEV_DB_PASSWORD |
Migrate the dev project. |
SUPABASE_PROD_PROJECT_REF, SUPABASE_PROD_DB_PASSWORD |
Migrate the prod project. |
RENDER_DEPLOY_HOOK_URL |
Deploys the production app after prod migrations. |
SOCKET_SECURITY_API_KEY |
Optional. Turns on CI’s Socket.dev scan. |
RENDER_DEPLOY_HOOK_URL is stored in the GitHub prod environment, so only the job
that promotes production can read it. It embeds a key= parameter, so the whole URL is
a credential that can deploy any commit to production. Get it from Render →
network-mapping-app → Settings → Deploy Hook. To rotate it, regenerate the hook in
Render.
On Render, the app services’ secrets are set in the dashboard. See Deployment.
packages/bluesky_to_graph
Section titled “packages/bluesky_to_graph”That package has its own .env.example: BSKY_SERVICE_URL, BSKY_IDENTIFIER,
BSKY_APP_PASSWORD, BSKY_OUTPUT_DIR, BSKY_CACHE_DIR, and tuning values
(BSKY_TOP_N_CANDIDATES, BSKY_FOLLOWER_SAMPLE_SIZE,
BSKY_MAX_CANDIDATE_FOLLOWER_COUNT, BSKY_MAX_FOLLOWER_FOLLOWS, BSKY_CONCURRENCY).