Environment variables
Required and optional configuration for the admin and storefront.
Each Next.js app loads its own .env file and validates it at startup. Shared
variables are defined in @prolifto/env; app-specific variables live in each
app's env.ts / env-schema.ts. Drizzle commands run from packages/db and
read packages/db/.env.
Start from the templates:
cp apps/admin/.env.example apps/admin/.env
cp apps/storefront/.env.example apps/storefront/.env
cp packages/db/.env.example packages/db/.envNever commit .env files or paste production values into documentation,
issues, or pull requests. Use your hosting provider's secret manager for
production.
Required for the admin app
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_APP_URL | Public URL of the admin app, e.g. http://localhost:3000 |
NEXT_PUBLIC_FRONTEND_URL | Public URL of the storefront, e.g. http://localhost:3001 |
DATABASE_URL | PostgreSQL connection string |
BETTER_AUTH_SECRET | Signing secret for sessions; must match the storefront |
NEXT_PUBLIC_TURNSTILE_SITE_KEY | Cloudflare Turnstile site key |
TURNSTILE_SECRET_KEY | Cloudflare Turnstile secret |
SMTP_FROM | Sender address for transactional email |
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS | SMTP connection |
GEMINI_API_KEY | Google Gemini key used for product description generation |
VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, NEXT_PUBLIC_VAPID_PUBLIC_KEY, VAPID_SUBJECT | Web push notifications |
STRIPE_ENABLED, POLAR_ENABLED | Payment feature flags ("true" or "false") |
Required for the storefront
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_APP_URL | Public URL of the storefront |
NEXT_PUBLIC_API_URL | Admin API base URL, e.g. http://localhost:3000 |
DATABASE_URL | Same database as the admin app |
BETTER_AUTH_SECRET | Must match the admin app |
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | Google sign-in for customers |
ORGANIZATION_SLUG | Store served by this storefront |
API_KEY | API key created in Settings → API |
NEXT_PUBLIC_TURNSTILE_SITE_KEY, TURNSTILE_SECRET_KEY | Cloudflare Turnstile |
SMTP_FROM, SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS | Transactional email |
Optional and integration-specific
Storage
STORAGE_PROVIDER is cloudinary by default. Set it to s3 to use an
S3-compatible provider.
- Cloudinary:
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,NEXT_PUBLIC_CLOUDINARY_PRESET_NAME,CLOUDINARY_API_KEY,CLOUDINARY_API_SECRET. - S3:
S3_ENDPOINT,S3_REGION,S3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEY,S3_BUCKET,S3_FORCE_PATH_STYLE,S3_PUBLIC_URL_BASE,S3_AUTO_CREATE_BUCKET,S3_AUTO_PUBLIC_READ.
Mirror S3_ENDPOINT / S3_PUBLIC_URL_BASE in the storefront so next/image
and the content security policy allow uploaded media.
Payments and billing
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET,NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYare required whenSTRIPE_ENABLED="true".POLAR_ACCESS_TOKEN,POLAR_WEBHOOK_SECRET,POLAR_SUCCESS_URLare required whenPOLAR_ENABLED="true". Polar is used for platform subscription billing.PLATFORM_ADMIN_EMAILSgrants platform administration access.NEXT_PUBLIC_BILLING_CONTACT_EMAILandBILLING_PAYMENT_INSTRUCTIONSare shown on the plan and billing page.
Email, SMS, and WhatsApp
- Local email is captured by Mailpit at
localhost:2525(SMTP) andlocalhost:8025(web UI). SMS_ENABLED,SMS_PROVIDER,SMS_SENDER_ID,SMS_API_URL,SMS_API_KEY,SMS_MONTHLY_QUOTA_PER_ORG, andSMS_DAILY_CAP_PER_RECIPIENTcontrol SMS. The defaultmockprovider is for development.WHATSAPP_ENABLED,WHATSAPP_GRAPH_API_VERSION,WHATSAPP_API_BASE_URL,WHATSAPP_DAILY_CAP_PER_ORG,WHATSAPP_DAILY_CAP_PER_RECIPIENT,WHATSAPP_EMBEDDED_SIGNUP_CONFIG_ID,META_APP_ID,META_APP_SECRET,META_VERIFY_TOKEN, andINTEGRATIONS_ENCRYPTION_KEYcontrol WhatsApp integration.
Search
Search uses PostgreSQL by default. Set SEARCH_PROVIDER="UPSTASH" plus
UPSTASH_SEARCH_REST_URL and UPSTASH_SEARCH_REST_TOKEN to use Upstash.
Background jobs
In production, set INNGEST_EVENT_KEY and INNGEST_SIGNING_KEY. Locally, the
Inngest dev server is started by pnpm dev:admin; override it with INNGEST_DEV
if port 8288 is unavailable.
PDFs
PUPPETEER_EXECUTABLE_PATH and PUPPETEER_NO_SANDBOX let you control the
Puppeteer runtime used for invoice and receipt PDFs.
Feature flags and logging
FEATURE_FLAGS='{"demoBadge":{"enabled":true,"rolloutPercentage":25}}'
FEATURE_FLAGS_DISABLED="false"
LOG_LEVEL="debug"Flag keys must exist in the registry in
packages/domain/src/feature-flags/registry.ts.
Storefront host handling
STOREFRONT_ROOT_DOMAIN and STOREFRONT_ALLOWED_HOSTS support subdomain and
custom-domain routing.
Environment precedence
The apps read environment variables at startup and fail fast when a required
value is missing. Conditional requirements are enforced too: for example,
Stripe keys are required only when STRIPE_ENABLED="true", and S3 keys only
when STORAGE_PROVIDER="s3".