Trovella Wiki

Routing & Pages

Next.js App Router structure, page patterns, middleware, and the server/client component boundary.

Trovella uses the Next.js 16 App Router with file-system routing, server components as the default rendering mode, and per-page authentication checks (not middleware). The middleware layer handles only Content Security Policy.

How Requests Flow Through the App

Browser request
  |
  v
middleware.ts (CSP nonce generation, skipped in dev and for /api/ routes)
  |
  v
next.config.ts (security headers: HSTS, X-Frame-Options, nosniff, etc.)
  |
  v
App Router file-system match
  |
  +-- /api/* routes --> Route Handlers (tRPC, auth, health, inngest, MCP, search)
  |
  +-- /auth/* pages --> Auth layout (centered card) --> Sign-in/sign-out
  |
  +-- /docs/* pages --> Fumadocs layout (public documentation)
  |
  +-- /wiki/* pages --> Fumadocs layout (internal wiki)
  |
  +-- All other pages --> Per-page auth check --> DashboardPage (server)
                            |
                            +-- ensurePersonalOrganization (idempotent)
                            +-- ensureActiveOrganization (idempotent)
                            |
                            v
                          Providers (client) --> DashboardShell (client) --> Content (client)

Key Design Decisions

Auth is per-page, not middleware. Each page server component calls getSession() and redirects to /auth/sign-in?callbackUrl=... if unauthenticated. This avoids the complexity of middleware-based auth and keeps auth logic co-located with the pages that need it. See ADR-005: Framework Decision for the full rationale.

CSP is middleware, not per-page. The middleware generates a per-request nonce and sets Content-Security-Policy-Report-Only. This is the one cross-cutting concern that genuinely benefits from middleware -- every HTML response needs the same CSP header. See Middleware & CSP.

Server components are the default. Pages and DashboardPage are server components that handle auth and org setup. Interactive content is pushed to client components below the Providers boundary. See Component Boundaries.

Route Categories

The application has four distinct route categories, each with different layout and auth behavior:

CategoryPath PatternLayoutAuthExamples
Dashboard pages/, /discover, /settings, /admin/*DashboardShell (sidebar + top bar)Required (per-page redirect)Home, Discover, Admin AI Logs
Auth pages/auth/*Centered card layoutNone (public)Sign-in
Content pages/docs/*, /wiki/*Fumadocs sidebar layoutNone (public)Public docs, Internal wiki
API routes/api/*None (JSON responses)Varies by endpointtRPC, health, auth callbacks

See Route Map for the complete inventory of every route.

On this page