Skip to content

Environment variables

Every environment variable each BabyMart app reads, whether it is required, and what it does.

Each app reads its own .env file in its own folder. The API holds every secret: the database, the JWT signing key, the payment gateways, uploads and email. The storefront and admin dashboard mostly need the API’s public address plus the Firebase web config for Google and GitHub sign-in.

flowchart LR
  W["apps/web/.env"] -->|NEXT_PUBLIC_API_URL| API
  A["apps/admin/.env"] -->|VITE_NEXT_PUBLIC_API_URL| API
  M["apps/mobile environment.ts"] -->|base URL| API
  API["apps/api/.env"] --> DB[(MongoDB)]
  API --> S[Stripe / SSLCommerz]
  API --> C[Cloudinary / S3]
  API --> E[SMTP email]

The API checks every variable against a Zod schema when it starts, and exits if a required one is missing. See apps/api/src/config/env.ts.

Variable Required Default Purpose
MONGO_URI Yes — MongoDB connection string.
JWT_SECRET Yes — Signs login tokens. Must be at least 32 characters when NODE_ENV=production, or the API exits.
NODE_ENV No development development, test or production. In development every CORS origin is allowed.
PORT No 8000 Port the API listens on (local and VPS hosting).
CLIENT_URL No http://localhost:3000 Storefront address. Added to CORS, and used in password-reset links and SSLCommerz redirects.
ADMIN_URL No — Admin dashboard address, added to the CORS allowlist.
SERVER_URL No http://localhost:8000 The API’s public address, used for SSLCommerz callback URLs.
STRIPE_SECRET_KEY For Stripe — Creates PaymentIntents and verifies Checkout Sessions.
STRIPE_WEBHOOK_SECRET For Stripe — Verifies POST /api/payments/webhook. The webhook rejects everything if it is missing.
SSLCOMMERZ_STORE_ID For SSLCommerz — SSLCommerz store ID.
SSLCOMMERZ_STORE_PASSWORD For SSLCommerz — SSLCommerz store password.
SSLCOMMERZ_IS_LIVE No sandbox true uses the live gateway, anything else uses the sandbox.
CLOUDINARY_CLOUD_NAME For uploads — Cloudinary account (default upload provider).
CLOUDINARY_API_KEY For uploads — Cloudinary key.
CLOUDINARY_API_SECRET For uploads — Cloudinary secret.
AWS_ACCESS_KEY_ID For S3 — AWS key, used when uploads go to S3.
AWS_SECRET_ACCESS_KEY For S3 — AWS secret.
AWS_REGION No us-east-1 S3 region.
AWS_S3_BUCKET_NAME For S3 — S3 bucket.
DEFAULT_UPLOAD_PROVIDER No cloudinary cloudinary or s3.
SMTP_HOST For email smtp.gmail.com Mail server for order and password-reset emails.
SMTP_PORT For email 587 Mail server port.
SMTP_USER For email SENDER_EMAIL_ADDRESS Mail login.
SMTP_PASS For email — Mail password (use a Gmail app password).
SENDER_EMAIL_ADDRESS For email — The “from” address.
FIREBASE_PROJECT_ID For OAuth — Accepts Firebase ID tokens on POST /api/auth/oauth. Without it those tokens are rejected.
GOOGLE_CLIENT_IDS For OAuth — Comma-separated Google client IDs, for Google ID tokens from the mobile app.
TAX_RATE No 0 Tax added to order totals on the server.
FREE_DELIVERY_THRESHOLD No 999 Order subtotal above which shipping is free. Below it, shipping is a flat 15.
DEFAULT_USER_IMAGE No — Avatar for new users.
MAX_PRODUCT_IMAGES No 5 Image limit per product.

Start from apps/web/.env.example. Only NEXT_PUBLIC_API_URL is checked as required (apps/web/lib/env-check.ts). Variables that start with NEXT_PUBLIC_ are sent to the browser, so never put a secret in one.

Variable Required Purpose
NEXT_PUBLIC_API_URL Yes The API’s address, e.g. http://localhost:8000. The /api prefix is added in code.
API_ENDPOINT No API address used by server-side rendering. Falls back to NEXT_PUBLIC_API_URL.
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY For Stripe Stripe publishable key.
STRIPE_SECRET_KEY For Stripe Server-only. Creates Checkout Sessions in /api/create-checkout-session.
STRIPE_WEBHOOK_SECRET For Stripe Server-only. Verifies /api/stripe-webhook.
NEXT_PUBLIC_FIREBASE_* For OAuth Seven Firebase web-config keys: API_KEY, AUTH_DOMAIN, PROJECT_ID, STORAGE_BUCKET, MESSAGING_SENDER_ID, APP_ID, MEASUREMENT_ID.
NEXT_PUBLIC_TAX_AMOUNT No Tax rate shown at checkout. Default 0.
NEXT_PUBLIC_FREE_DELIVERY_THRESHOLD No Free-shipping threshold shown at checkout. Default 999.
NEXT_PUBLIC_AVAILABLE_COUNTRIES No JSON list of countries offered in the address form.
NEXT_PUBLIC_SITE_URL No Public storefront URL for Stripe success and cancel links. Defaults to the request’s origin.
NEXT_PUBLIC_GTM_ID No Google Tag Manager container.
NEXT_PUBLIC_SHOW_CONSOLE_WARNING No Shows a warning in the browser console.
NEXT_PUBLIC_APP_ENV, NODE_ENV No Environment flags.
NEXT_PUBLIC_TURBO_PURCHASE_LINK, NEXT_PUBLIC_NORMAL_PURCHASE_LINK, NEXT_PUBLIC_GITHUB_REPO_LINK No Links shown in the storefront’s promo banners.
ANTHROPIC_API_KEY No Server-only Claude API key for the on-site assistant. Without it the assistant answers from its built-in knowledge base.
ASSISTANT_MODEL No Claude model id for the assistant. Default claude-opus-5-5.
ASSISTANT_GUEST_DAILY_LIMIT, ASSISTANT_USER_DAILY_LIMIT No AI replies per visitor per day. Defaults 5 (guests) and 20 (signed in).

There is no .env.example for the admin, so create the file by hand. Vite only exposes variables that start with VITE_.

Variable Required Purpose
VITE_NEXT_PUBLIC_API_URL Yes The API’s address, without /api. The admin throws an error at startup without it (apps/admin/src/lib/config.ts).
VITE_FIREBASE_* Yes The same seven Firebase web-config keys as the storefront. Without VITE_FIREBASE_API_KEY the admin shows a full-page error, even for email sign-in.
VITE_APP_ENV No Environment flag.
VITE_MAX_PRODUCT_IMAGES No Image limit in the product form. Default 5.
VITE_SHOW_DUMMY_DATA No true fills dashboards with sample numbers.

The mobile app does not read a .env file: no package loads it, so apps/mobile/.env.example has no effect. The API address is chosen in apps/mobile/src/config/environment.ts› getApiBaseUrl:

  • iOS simulator → http://localhost:8000/api
  • Android emulator → http://10.0.2.2:8000/api

The Stripe publishable key is set in apps/mobile/App.tsx, and the Google sign-in client IDs in apps/mobile/src/services/googleAuthService.ts. Replace both with your own values.