shipanysaas
Documentation
Back
  • Getting started
    • Install and run
    • Project structure
    • Configuration
    • Commands
  • Coding agents
    • Agent skills
  • Authentication
    • Email sign-in
    • OAuth providers
    • Two-step sign-in and passkeys
  • Database
    • Migrations
    • Row-level security
    • Database tests
    • Reading and writing data
  • Features
    • Teams and invitations
    • Email
    • File uploads
    • Blog, docs and changelog
  • Billing
    • Stripe and Lemon Squeezy
    • Pricing plans
    • Webhooks
  • Live demo
  • Configuration

    Where settings live: the env files, the typed config files in apps/web/config, and the database config row.

    Settings live in three places:

    1. Env files in apps/web. They hold values that change per environment.
    2. Config files in apps/web/config. They read the env values, validate them with Zod and export typed objects. An invalid value stops the app at startup or at build time.
    3. The public.config row in the database. It holds the billing provider and three on/off switches the database itself checks.

    Env files

    FileCommittedHolds
    apps/web/.envYesPublic values shared by every environment: site name, auth methods, feature flags
    apps/web/.env.developmentYesLocal Supabase URL and keys, local mail server
    apps/web/.env.productionYesPublic production values only
    apps/web/.env.testYesValues for the CI and end-to-end test build
    apps/web/.env.localNo (ignored by Git)Your secrets on your machine

    Put secrets (Supabase secret key, Stripe keys, mail passwords) in .env.local locally and in your host's environment settings in production. Never in a committed file.

    NEXT_PUBLIC_* values are read when the server starts, so restart pnpm dev after you change one.

    Site

    VariableNotes
    NEXT_PUBLIC_SITE_URLMust be https:// in a production build (config/app.config.ts fails the build otherwise)
    NEXT_PUBLIC_PRODUCT_NAME, NEXT_PUBLIC_SITE_TITLE, NEXT_PUBLIC_SITE_DESCRIPTIONName and default metadata
    NEXT_PUBLIC_DEFAULT_THEME_MODElight, dark or system
    NEXT_PUBLIC_THEME_COLOR, NEXT_PUBLIC_THEME_COLOR_DARKBrowser theme colours. They must differ.

    Supabase

    VariableNotes
    NEXT_PUBLIC_SUPABASE_URLProject URL
    NEXT_PUBLIC_SUPABASE_PUBLIC_KEYPublic (anon) key
    SUPABASE_SECRET_KEYSecret key. Read only in server-only modules; it bypasses row-level security
    SUPABASE_DB_WEBHOOK_SECRETShared secret the database webhook sends to /api/db/webhook

    Feature flags

    config/feature-flags.config.ts reads these. The code default applies when a variable is not set.

    VariableCode defaultIn .env
    NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTStruetrue
    NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_CREATIONtruetrue
    NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_ONLYfalsefalse
    NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_DELETIONfalsetrue
    NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_DELETIONfalsetrue
    NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLINGfalsetrue
    NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLINGfalsetrue
    NEXT_PUBLIC_ENABLE_NOTIFICATIONStruenot set
    NEXT_PUBLIC_REALTIME_NOTIFICATIONSfalsenot set
    NEXT_PUBLIC_ENABLE_THEME_TOGGLEtruetrue
    NEXT_PUBLIC_ENABLE_VERSION_UPDATERfalsenot set
    NEXT_PUBLIC_LANGUAGE_PRIORITYapplicationapplication

    With NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_ONLY=true, the personal workspace is skipped: users land in their last team, or on the create-team page if they have none.

    Other areas

    Each of these has its own page:

    • Sign-in methods, captcha and password rules: Authentication.
    • NEXT_PUBLIC_BILLING_PROVIDER and the Stripe and Lemon Squeezy keys: Stripe and Lemon Squeezy.
    • MAILER_PROVIDER, EMAIL_*, RESEND_API_KEY, CONTACT_EMAIL: Email.
    • CMS_CLIENT and the content path: Blog, docs and changelog.
    • NEXT_PUBLIC_DEMO_*: Live demo.

    A few more that are off by default:

    VariableEffect
    NEXT_PUBLIC_MONITORING_PROVIDERsentry turns on Sentry (with NEXT_PUBLIC_SENTRY_DSN). Empty logs errors to the console.
    ENABLE_STRICT_CSPtrue turns on the strict Content Security Policy in apps/web/proxy.ts. Default false.
    ENABLE_REACT_COMPILERtrue turns on the React Compiler in next.config.mjs

    The NEXT_PUBLIC_KIT_* variables and config/kit-offer.config.ts drive the kit's own sales page (prices, payment links, demo link). Replace them with your own offer, or remove that page, when you build your product.

    Config files

    FileWhat it sets
    app.config.tsName, title, description, URL, theme, locale
    auth.config.tsSign-in methods, captcha key, terms checkbox, identity linking
    feature-flags.config.tsThe flags above
    paths.config.tsRoutes for sign-in, the app, settings, billing and invitations
    billing.config.tsYour products and plans. It re-exports billing.sample.config.ts until you replace it
    personal-account-navigation.config.tsx, team-account-navigation.config.tsxSidebar links
    demo.config.tsLive demo mode
    kit-offer.config.tsThe kit's own sales page

    The database config row

    apps/web/supabase/schemas/02-config.sql creates public.config with enable_team_accounts, enable_account_billing, enable_team_account_billing (all true) and billing_provider (stripe). If you switch to Lemon Squeezy, update billing_provider here as well as NEXT_PUBLIC_BILLING_PROVIDER.