Prolifto
Getting started

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/.env

Never 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

VariablePurpose
NEXT_PUBLIC_APP_URLPublic URL of the admin app, e.g. http://localhost:3000
NEXT_PUBLIC_FRONTEND_URLPublic URL of the storefront, e.g. http://localhost:3001
DATABASE_URLPostgreSQL connection string
BETTER_AUTH_SECRETSigning secret for sessions; must match the storefront
NEXT_PUBLIC_TURNSTILE_SITE_KEYCloudflare Turnstile site key
TURNSTILE_SECRET_KEYCloudflare Turnstile secret
SMTP_FROMSender address for transactional email
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSSMTP connection
GEMINI_API_KEYGoogle Gemini key used for product description generation
VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, NEXT_PUBLIC_VAPID_PUBLIC_KEY, VAPID_SUBJECTWeb push notifications
STRIPE_ENABLED, POLAR_ENABLEDPayment feature flags ("true" or "false")

Required for the storefront

VariablePurpose
NEXT_PUBLIC_APP_URLPublic URL of the storefront
NEXT_PUBLIC_API_URLAdmin API base URL, e.g. http://localhost:3000
DATABASE_URLSame database as the admin app
BETTER_AUTH_SECRETMust match the admin app
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETGoogle sign-in for customers
ORGANIZATION_SLUGStore served by this storefront
API_KEYAPI key created in Settings → API
NEXT_PUBLIC_TURNSTILE_SITE_KEY, TURNSTILE_SECRET_KEYCloudflare Turnstile
SMTP_FROM, SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSTransactional 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_KEY are required when STRIPE_ENABLED="true".
  • POLAR_ACCESS_TOKEN, POLAR_WEBHOOK_SECRET, POLAR_SUCCESS_URL are required when POLAR_ENABLED="true". Polar is used for platform subscription billing.
  • PLATFORM_ADMIN_EMAILS grants platform administration access.
  • NEXT_PUBLIC_BILLING_CONTACT_EMAIL and BILLING_PAYMENT_INSTRUCTIONS are shown on the plan and billing page.

Email, SMS, and WhatsApp

  • Local email is captured by Mailpit at localhost:2525 (SMTP) and localhost:8025 (web UI).
  • SMS_ENABLED, SMS_PROVIDER, SMS_SENDER_ID, SMS_API_URL, SMS_API_KEY, SMS_MONTHLY_QUOTA_PER_ORG, and SMS_DAILY_CAP_PER_RECIPIENT control SMS. The default mock provider 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, and INTEGRATIONS_ENCRYPTION_KEY control WhatsApp integration.

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".

On this page