Skip to main content

What It Does

apps/web-interim is a standalone Next.js 14 app that supports the mobile app with auth callbacks, deep link verification, content redirects, and a landing page with waitlist signup.
This is a SEPARATE app from the full web client (apps/web). They have separate package.json, node_modules, and codebases. The web interim does NOT have API routes for content CRUD — those live in apps/web.

Architecture

LayerTechnology
FrameworkNext.js 14 (App Router)
StylingTailwind CSS (no CSS Modules)
AuthSupabase browser client (@supabase/ssr)
DeploymentVercel
FontsCormorant Garamond / Fraunces (serif)

Pages

RouteComponentPurpose
/page.tsxLanding page with waitlist signup
/auth/confirmRoute handlerServer-side OTP verification — handles email confirmation, password recovery, and email change tokens
/confirmation-successConfirmationSuccessEmail verified success
/reset-passwordResetPasswordPassword reset form
/email-change-pendingEmailChangePendingWaiting for new email confirmation
/change-emailChangeEmailEmail change success
/auth/auth-errorAuthErrorAuth link invalid/expired
/recipes/[id]AppOnlyContentRecipe deep link redirect
/posts/[id]AppOnlyContentPost deep link redirect
/collections/[id]AppOnlyContentCollection deep link redirect
/.well-known/apple-app-site-associationRoute handlerAASA for iOS universal links
/.well-known/assetlinks.jsonRoute handlerAndroid Asset Links
/api/waitlistRoute handlerWaitlist signup via marketing-events Supabase edge function
The app also includes error.tsx (global error boundary) and not-found.tsx (404 page) at the root layout level.

Auth Callback Flow

The /auth/confirm route handler is the central entry point for all Supabase email link callbacks. When a user clicks a link in a confirmation, recovery, or email change email, the link points to this route with a token_hash and type parameter. The route calls supabase.auth.verifyOtp() server-side, then redirects based on the OTP type:
OTP TypeRedirect ToPurpose
signup or email/confirmation-successEmail address confirmed after registration
recovery/reset-passwordPassword reset — user enters new password
email_change/change-emailEmail change confirmed
(any error)/auth/auth-errorToken invalid, expired, or missing
The AuthCallbackHandler component (used on pages like /confirmation-success) handles a secondary path: PKCE code exchange via URL query params and hash fragment token parsing for cases where the redirect includes tokens in the URL fragment rather than as query parameters.

Components

ComponentPurpose
AuthCallbackHandlerProcesses auth tokens from email links (PKCE code exchange + hash fragment handling)
RecoveryHandlerBackup handler for recovery hash fragments (possibly redundant with /auth/confirm)
AppOnlyContentContent redirect page — deep link attempt + “app only” fallback with waitlist

Design Language

  • Monochrome palette (#111111 primary, #fafafa backgrounds, #777777 secondary text)
  • Cormorant Garamond / Fraunces serif fonts for headings
  • Film-strip sprocket edge decorations on desktop
  • Grain overlay texture
  • Staggered entrance animations (cubic-bezier easing)
  • Consistent accent lines (gradient top/bottom borders)

Key Differences from apps/web

AspectWeb InterimFull Web Client
API routesNo content CRUDAll API routes
MiddlewareNoneAuth-based route protection
Supabase clientBrowser-onlyServer + browser
Shared packageNo dependencyUses @recipe-room/shared
node_modulesStandaloneHoisted from monorepo root
ScopeAuth callbacks, redirects, landingFull web application

Landing Page & Waitlist

The home page is a branded landing page with:
  • Hero section with app description and waitlist form
  • Feature highlights
  • Film-strip visual motif
  • Waitlist form → POST /api/waitlistmarketing-events edge function → Loops.so API
  • Responsive design (mobile + desktop)
The /api/waitlist route now uses the marketing-events Supabase edge function, which reads the Loops API key from edge function secrets. No API keys are stored in the web-interim codebase.

Web Client Middleware (apps/web only)

apps/web/src/middleware.ts implements Next.js middleware for auth-based route protection. This exists in the full web client, NOT in the web interim.
Route TypeExamplesBehavior
Protected/settings, /saved, /create/*, /meRedirect to /login if unauthenticated
Public/, /login, /register, /recipes/*, /posts/*Accessible to all
Uses @supabase/ssr createServerClient with cookie handling. Phase 2 consideration when the full web client is refactored.