Creator
Codebase

Codebase Overview

How Creator's codebase is organized and how the pieces fit together.

Architecture

Creator is a Next.js 16 App Router application. Routes are organized into route groups that control access:

Route GroupLayoutAccess
app/(public)/Navbar + FooterAnyone
app/(protected)/Sidebar + BreadcrumbsAuthenticated users only
app/(protected)/admin/Sidebar + BreadcrumbsAdmin role only
app/auth/Centered cardUnauthenticated users only
app/api/None (API routes)Varies per endpoint

How route protection works

Route protection is handled by proxy.ts (Next.js middleware). Every route is protected by default — only routes listed in the publicRoutes array (config/public-routes.config.ts) are accessible without authentication.

The proxy handles three cases:

  • Unauthenticated users visiting a non-public, non-auth route are redirected to /auth/login with a callbackUrl parameter.
  • Non-admin users visiting /admin routes are redirected to the dashboard.
  • Authenticated users visiting auth routes (login, signup) are redirected to the dashboard.

API routes add a second layer of protection using requireApiAuth() or requireApiAdmin() from lib/auth/api-guard.ts, which return error responses instead of redirecting.

Key directories

config/         → Centralized configuration (app, billing, routes, menus)
lib/auth/       → NextAuth config, guards, adapter, utilities
lib/db/         → Drizzle schema, database client, query modules
lib/services/   → Email, storage, Stripe, Lemon Squeezy, GitHub
lib/schemas/    → Zod validation schemas
components/ui/  → shadcn/ui components
components/shared/ → Reusable app components (Logo, Footer, Analytics, etc.)
hooks/          → Custom React hooks

Request flow

  1. User visits a page
  2. proxy.ts checks if the route is public — if not, redirects unauthenticated users to login
  3. Next.js matches the route to a route group
  4. The page component renders (server component by default)
  5. Client components hydrate where needed ("use client" directive)

For API routes:

  1. Request hits app/api/[feature]/route.ts
  2. Guard function checks auth (requireApiAuth() / requireApiAdmin())
  3. If guard fails, error response is returned immediately
  4. If guard passes, handler logic runs with the authenticated userId

On this page

We use cookies to ensure you get the best experience on our website. For more information on how we use cookies, please see our cookie policy.