Skip to main content
Create a .env.local file in the project root. This file is ignored by git and is never committed to version control.

Required variables

These two variables are required for the app to start. Without them, all Supabase calls will fail.
.env.local
NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
VariableDescription
NEXT_PUBLIC_SUPABASE_URLThe base URL of your Supabase project. Found in Project Settings → API → Project URL.
NEXT_PUBLIC_SUPABASE_ANON_KEYThe public anon key for your Supabase project. Found in Project Settings → API → Project API keys. This key is safe to expose in the browser — access is controlled by Row Level Security policies.
Do not use the service_role key in .env.local. It bypasses all RLS policies and would give any browser session full database access.

Scheduler API variables

The Go Scheduler API is called server-side when Auto-Assign is triggered. These variables configure the connection.
.env.local
SCHEDULER_API_KEY=your-hmac-api-key
SCHEDULER_API_URL=https://shift-scheduler-api-3nxm.vercel.app
VariableDescription
SCHEDULER_API_KEYHMAC key used to sign requests to the Go Scheduler API. Obtain this from the API Admin dashboard.
SCHEDULER_API_URLBase URL for the Go Scheduler API. Defaults to the hosted instance if not set. Override this if you are running your own instance of the scheduler.
The Go Scheduler API is an external service — you do not need to run it locally. The hosted instance at shift-scheduler-api-3nxm.vercel.app is available for use. API authentication uses stateless HMAC signatures, so no session management is required.

Site URL

Required for email-based flows (invitation links, password reset) to construct absolute callback URLs.
.env.local
NEXT_PUBLIC_SITE_URL=https://your-domain.com
In local development, set this to http://localhost:3000.

SMTP (email)

Used for sending event invitation emails via Nodemailer. All five variables must be set together for email to work.
.env.local
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-smtp-username
SMTP_PASS=your-smtp-password
CONTACT_EMAIL=admin@your-domain.com
VariableDescription
SMTP_HOSTHostname of your SMTP server (e.g., smtp.gmail.com, smtp.sendgrid.net).
SMTP_PORTSMTP port. Use 587 for STARTTLS or 465 for SSL.
SMTP_SECURESet to true for port 465 (SSL), false for port 587 (STARTTLS).
SMTP_USERSMTP authentication username.
SMTP_PASSSMTP authentication password or app-specific password.
CONTACT_EMAILThe recipient address for contact form submissions.
Email sending is optional. If SMTP variables are not configured, event invitations will not be sent. Admins can still be added manually via the event admin panel.

Broadcast Hub (email blasts)

Used for sending bulk email announcements to volunteers from the Broadcast page (/events/[id]/broadcast). The Broadcast Hub rotates sends across three Gmail accounts to stay within Gmail’s per-account sending limits. All six variables must be set together for broadcasting to work.
.env.local
GMAIL_USER_1=account1@gmail.com
GMAIL_PASS_1=app-password-1
GMAIL_USER_2=account2@gmail.com
GMAIL_PASS_2=app-password-2
GMAIL_USER_3=account3@gmail.com
GMAIL_PASS_3=app-password-3
VariableDescription
GMAIL_USER_1 / GMAIL_USER_2 / GMAIL_USER_3Gmail addresses used as rotating send accounts.
GMAIL_PASS_1 / GMAIL_PASS_2 / GMAIL_PASS_3App-specific passwords for each Gmail account. Generate these in Google Account → Security → App passwords.
Recipients are added as BCC (blind carbon copy) on each batch to protect their privacy. Batches are capped at 25 recipients per send to stay within Gmail limits.

Axiom logging (optional)

Shift Scheduler integrates with Axiom for server-side logging and Web Vitals tracking via @axiomhq/nextjs. These variables are optional — the app runs normally without them.
.env.local
NEXT_PUBLIC_AXIOM_TOKEN=your-axiom-ingest-token
NEXT_PUBLIC_AXIOM_DATASET=your-dataset-name
VariableDescription
NEXT_PUBLIC_AXIOM_TOKENYour Axiom ingest token. Found in Axiom → Settings → API Tokens.
NEXT_PUBLIC_AXIOM_DATASETThe Axiom dataset name to write events to.
Axiom logging is useful in production to capture Next.js Web Vitals (LCP, FID, CLS) and server-side errors. Skip it for local development.

Full example

.env.local
# Required
NEXT_PUBLIC_SUPABASE_URL=https://abcdefghijkl.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# Scheduler API
SCHEDULER_API_KEY=your-hmac-key
SCHEDULER_API_URL=https://shift-scheduler-api-3nxm.vercel.app

# Site URL
NEXT_PUBLIC_SITE_URL=http://localhost:3000

# SMTP (optional)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=you@example.com
SMTP_PASS=app-password
CONTACT_EMAIL=admin@example.com

# Broadcast Hub (optional)
GMAIL_USER_1=account1@gmail.com
GMAIL_PASS_1=app-password-1
GMAIL_USER_2=account2@gmail.com
GMAIL_PASS_2=app-password-2
GMAIL_USER_3=account3@gmail.com
GMAIL_PASS_3=app-password-3

# Axiom (optional)
NEXT_PUBLIC_AXIOM_TOKEN=xaat-...
NEXT_PUBLIC_AXIOM_DATASET=shift-scheduler-logs

Build docs developers (and LLMs) love