Environment Variables
Configure environment variables and connect services for the Next.js template.
Configuration lives in .env (copied from .env.example). This page is the
reference for every variable the template reads, grouped by service. Each is
marked:
- Required (core) — the app will not start or core auth breaks without it.
- Required (feature) — needed only if you use that feature.
- Optional — has a default or only changes behavior.
Server secrets vs. public values. Variables prefixed with NEXT_PUBLIC_
are inlined into the browser bundle at build time and are visible to
users — never put secrets there. Everything else is server-only. Because
NEXT_PUBLIC_* values are fixed at build, changing them requires a rebuild.
Core
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL | Required (core) | PostgreSQL connection string, e.g. postgresql://user:password@localhost:5432/soar_next. |
Better Auth
| Variable | Required | Notes |
|---|---|---|
BETTER_AUTH_SECRET | Required (core) | Secret used to sign sessions. Generate with openssl rand -base64 32. Keep it stable; changing it invalidates sessions. |
BETTER_AUTH_URL | Required (core) | Base URL of the app. http://localhost:3000 locally; your canonical HTTPS URL in production. |
Better Auth reads these from the environment automatically — they are not passed
through process.env in src/lib/auth.ts. See
Authentication.
OAuth providers
Both providers are optional. If you don't configure one, hide its button rather than leaving a non-functional control — see Authentication.
| Variable | Required | Notes |
|---|---|---|
GITHUB_CLIENT_ID | Required (feature) | GitHub OAuth app client ID. |
GITHUB_CLIENT_SECRET | Required (feature) | GitHub OAuth app secret. |
GOOGLE_CLIENT_ID | Required (feature) | Google OAuth client ID. |
GOOGLE_CLIENT_SECRET | Required (feature) | Google OAuth client secret. |
Creem payments
| Variable | Required | Notes |
|---|---|---|
CREEM_SERVER_IDX | Optional | Selects the Creem server (sandbox vs. live). Defaults to 0 when unset (src/lib/payment/creem.ts). |
CREEM_API_KEY | Required (feature) | Creem API key for creating checkouts. |
CREEM_WEBHOOK_SECRET | Required (feature) | Verifies incoming webhook signatures. |
NEXT_PUBLIC_CREEM_PRODUCT_PRO_MONTHLY | Required (feature) | Public Creem product ID for the Pro monthly plan. Build-time, exposed to the browser. |
NEXT_PUBLIC_CREEM_PRODUCT_PRO_YEARLY | Required (feature) | Public Creem product ID for the Pro yearly plan. |
NEXT_PUBLIC_CREEM_PRODUCT_LIFETIME | Required (feature) | Public Creem product ID for the Lifetime plan. |
These map the Free / Pro / Lifetime pricing plans to Creem products; they are
distinct from the display prices in src/config/price-config.ts. See
Payments.
Resend email
| Variable | Required | Notes |
|---|---|---|
RESEND_API_KEY | Required (feature) | Resend API key. Needed for email verification, password reset, and the contact form. Without it, email verification blocks login. |
The sender and support addresses are set in src/config/website-config.ts
(fromEmail, supportEmail), not via env. See Email.
OpenAI (AI chat)
| Variable | Required | Notes |
|---|---|---|
OPENAI_API_KEY | Required (feature) | Used by the streaming chat route. The OpenAI SDK reads it from the environment automatically. See AI Chat. |
Replicate (AI media)
| Variable | Required | Notes |
|---|---|---|
REPLICATE_API_TOKEN | Required (feature) | Used by the image/video/audio generation routes. The Replicate SDK reads it automatically. See AI Media. |
Site & demo
| Variable | Required | Notes |
|---|---|---|
NEXT_PUBLIC_SITE_URL | Optional | Canonical site URL used for metadataBase in src/app/[locale]/layout.tsx and the marketing page. Falls back to https://soarstarter.com if unset. Public, build-time. |
NEXT_PUBLIC_IS_DEMO | Optional | When "true", toggles demo behavior in the dashboard sidebar (src/config/user-sidebar-config.ts). Public, build-time. |
Both NEXT_PUBLIC_SITE_URL and NEXT_PUBLIC_IS_DEMO are read by the app but
are not in .env.example — add them yourself. Set NEXT_PUBLIC_SITE_URL
to your real domain in production so Open Graph and canonical metadata resolve
correctly; otherwise it falls back to the SoarStarter default. Leave
NEXT_PUBLIC_IS_DEMO unset (or any value other than "true") for normal
behavior.
Local vs. production
- Local:
BETTER_AUTH_URL=http://localhost:3000, a local or dev database, andCREEM_SERVER_IDXpointed at sandbox. - Production: your canonical HTTPS
BETTER_AUTH_URLandNEXT_PUBLIC_SITE_URL, a hosted database with pooling, live Creem server and product IDs, a verified Resend domain, and a freshBETTER_AUTH_SECRET. Remember thatNEXT_PUBLIC_*changes require a rebuild. See Deployment.
