Skip to main content
Variables with the NEXT_PUBLIC_ prefix are exposed to the browser. Do not place server-only secrets behind that prefix.

Core app and Supabase

VariableUsed whenRequired?Notes
NEXT_PUBLIC_SUPABASE_URLAuth or app data is activeYes, for auth/dataSupabase project URL
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYAuth or app data is activeYes, for auth/dataSupabase publishable or anon key
SUPABASE_SERVICE_ROLE_KEYBilling, admin, avatar, webhook, audit, persistent rate limitsYes, for server-only featuresNever expose this to the client
NEXT_PUBLIC_APP_URLRecommended in all environmentsStrongly recommendedApp base URL for callbacks, order pages, and metadata

Feature toggles

If a toggle is not set, the repository treats that feature as enabled. Set false, 0, no, or off to disable it.
VariablePurpose
NEXT_PUBLIC_ENABLE_AUTHControls login, signup, dashboard, settings, and auth-aware shell
NEXT_PUBLIC_ENABLE_WAITLISTControls the waitlist page and API
NEXT_PUBLIC_ENABLE_CONTACTControls the contact form
NEXT_PUBLIC_ENABLE_PAYMENTSControls billing, checkout, and payment-related UI
NEXT_PUBLIC_ENABLE_ADMINControls the admin dashboard
NEXT_PUBLIC_ENABLE_AIControls AI routes and related UI

Payments

VariableRequired whenNotes
PAYMENT_PROVIDERPayments are enabledValid values: midtrans or doku
MIDTRANS_SERVER_KEYPAYMENT_PROVIDER=midtransServer-only Midtrans secret
NEXT_PUBLIC_MIDTRANS_CLIENT_KEYPAYMENT_PROVIDER=midtransClient key used to open the Snap popup
DOKU_CLIENT_IDPAYMENT_PROVIDER=dokuDoku merchant client ID
DOKU_SECRET_KEYPAYMENT_PROVIDER=dokuDoku merchant secret key

Email and contact

VariableRequired whenNotes
RESEND_API_KEYContact form or email is enabledResend API key
EMAIL_FROMRecommended when email is enabledSender address. If empty, the repo falls back to the default KilatKoding sender
CONTACT_EMAILOptionalDestination inbox for the contact form. If empty, it falls back to EMAIL_FROM

Admin and access control

VariableRequired whenNotes
ADMIN_EMAILSOptionalComma-separated bootstrap admin email list
ADMIN_EMAILS is not the final source of truth. After the user signs in, the repository manages real access through the user_roles table.

AI

VariableRequired whenNotes
AI_DEFAULT_PROVIDERAI is enabledValid values: openai or anthropic
OPENAI_API_KEYAI_DEFAULT_PROVIDER=openaiSecret used by OpenAI AI routes
ANTHROPIC_API_KEYAI_DEFAULT_PROVIDER=anthropicSecret used by Anthropic AI routes

Optional env for operations

VariableUsed byNotes
VERCEL_URLMetadata base URL during deployUsually filled automatically by Vercel
PLAYWRIGHT_BASE_URLPlaywrightLets E2E tests target an already running server
CIGitHub Actions or another CI environmentChanges Playwright retries and reporter behavior

Common toggle profiles

This section helps when you want to start from a realistic feature combination instead of keeping everything enabled at once.
Good when you are still validating demand.
NEXT_PUBLIC_ENABLE_AUTH=false
NEXT_PUBLIC_ENABLE_WAITLIST=true
NEXT_PUBLIC_ENABLE_CONTACT=true
NEXT_PUBLIC_ENABLE_PAYMENTS=false
NEXT_PUBLIC_ENABLE_ADMIN=false
NEXT_PUBLIC_ENABLE_AI=false
You still need NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY because waitlist depends on Supabase. If contact is enabled, you also need RESEND_API_KEY.
Good for most classic SaaS products.
NEXT_PUBLIC_ENABLE_AUTH=true
NEXT_PUBLIC_ENABLE_WAITLIST=false
NEXT_PUBLIC_ENABLE_CONTACT=true
NEXT_PUBLIC_ENABLE_PAYMENTS=true
NEXT_PUBLIC_ENABLE_ADMIN=true
NEXT_PUBLIC_ENABLE_AI=false

PAYMENT_PROVIDER=doku
Make sure Supabase public env, SUPABASE_SERVICE_ROLE_KEY, and the chosen payment provider credentials are filled in.
Good when AI is a core product feature.
NEXT_PUBLIC_ENABLE_AUTH=true
NEXT_PUBLIC_ENABLE_WAITLIST=false
NEXT_PUBLIC_ENABLE_CONTACT=false
NEXT_PUBLIC_ENABLE_PAYMENTS=true
NEXT_PUBLIC_ENABLE_ADMIN=true
NEXT_PUBLIC_ENABLE_AI=true

PAYMENT_PROVIDER=midtrans
AI_DEFAULT_PROVIDER=openai
In addition to payment env, you also need OPENAI_API_KEY or ANTHROPIC_API_KEY depending on the default provider.
Good for gated product areas, internal dashboards, or client workspaces.
NEXT_PUBLIC_ENABLE_AUTH=true
NEXT_PUBLIC_ENABLE_WAITLIST=false
NEXT_PUBLIC_ENABLE_CONTACT=false
NEXT_PUBLIC_ENABLE_PAYMENTS=false
NEXT_PUBLIC_ENABLE_ADMIN=false
NEXT_PUBLIC_ENABLE_AI=false
The minimum setup is just Supabase. You can enable admin later if you need an internal operations panel.

Minimal .env.local example

Use this if you only want auth, dashboard, and one payment provider:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=
SUPABASE_SERVICE_ROLE_KEY=
NEXT_PUBLIC_APP_URL=http://localhost:3000

NEXT_PUBLIC_ENABLE_AUTH=true
NEXT_PUBLIC_ENABLE_WAITLIST=false
NEXT_PUBLIC_ENABLE_CONTACT=false
NEXT_PUBLIC_ENABLE_PAYMENTS=true
NEXT_PUBLIC_ENABLE_ADMIN=true
NEXT_PUBLIC_ENABLE_AI=false

PAYMENT_PROVIDER=doku
DOKU_CLIENT_ID=
DOKU_SECRET_KEY=

ADMIN_EMAILS=you@example.com

Quick way to verify env values

  1. Run npm run env:check.
  2. Read the status for each feature: ready, fallback mode, or disabled by ....
  3. After the app is live, open GET /api/health for a more detailed readiness summary.
If a feature is not part of your product yet, it is better to disable it explicitly than to leave it half-configured.