Enable prelaunch mode to collect waitlist signups before your product launches. Toggle with NEXT_PUBLIC_PRELAUNCH=true in your .env.local, or configure it during npm run init (Step 2c: Features). In application code, always read the flag via appConfig.features.prelaunch rather than process.env.NEXT_PUBLIC_PRELAUNCH directly.

What Changes in Prelaunch Mode

Component Normal Mode Prelaunch Mode
Hero Section CTA buttons (Get Started, Learn More) Waitlist signup form
Social Proof Visible (user count, ratings) Hidden
Login Button Visible in navbar Hidden (desktop & mobile)
Sign-In (server-side) Open to anyone Allowlist-gated (see below). Login page remains reachable for admins.
Pricing Buttons Buy/Subscribe buttons "Coming soon" (disabled)
Testimonials Visible Hidden

Sign-In Allowlist (server-side gate)

Hiding the login button is purely cosmetic — nothing prevents a visitor from typing /login directly or completing an in-flight OAuth callback. Prelaunch mode therefore also gates authentication server-side via an email allowlist:

# Server-only (no NEXT_PUBLIC_ prefix). Comma-separated, case-insensitive.
# Empty = sign-in is fully locked (you'll be unable to log in yourself).
[email protected],[email protected]

The gate fires at three points, all routed through the isPrelaunchEmailAllowed() helper exported from config/app.ts:

Enforcement point Behavior on non-allowlisted email
POST /api/auth/magic-link Returns 403 with code PRELAUNCH_RESTRICTED before calling Supabase generateLink, so no auth.users row is created.
GET /[locale]/callback (magic-link path) Belt-and-suspenders: if the allowlist shrinks while a valid link is in flight, the user is signed out and redirected to ?error=prelaunch.
GET /[locale]/callback (OAuth path) OAuth always creates the auth user during exchangeCodeForSession. The handler signs out and calls supabaseAdmin.auth.admin.deleteUser(...) to undo the cascade-created profile/account/membership. Without this, every OAuth attempt by a stranger would leave an orphan auth row — exactly the symptom that motivated the gate.
Operator notes
  • Add yourself to PRELAUNCH_ALLOWED_EMAILS before flipping NEXT_PUBLIC_PRELAUNCH=true, or you'll lock yourself out.
  • The error message is generic ("Authentication is currently restricted to invited users") to avoid revealing whether an email exists in your DB.
  • The login page shows a localized amber banner explaining the restriction (translation key auth.login.prelaunchRestricted).
  • Orphan auth.users rows created before the gate was wired need manual cleanup in the Supabase dashboard.

Waitlist Features

  • Email validation with error states
  • Loading spinner during submission
  • Success confirmation with check icon
  • Optional spots remaining counter
  • Optional total waiters count
  • Newsletter integration via pluggable email provider (Brevo / Mailjet)
  • Three variants: default, centered, glass card