All paths below are relative to frontend/apps/saas/app. Route groups (folders in parentheses) do not appear in the URL.

Top level

server-client-boundary.test.ts also sits here. It is a test, not a route. See Testing.

(unauthenticated)

Layout: SessionProvider and AuthWrapper (logo, locale switch, colour mode toggle, a centered card). All five pages export dynamic = "force-dynamic" and revalidate = 0.

(start)

The folder holds the whole wizard: StartWizard.tsx, SignupPopup.tsx, DesignPopup.tsx, AutofitMigration.tsx, steps.tsx, screens.tsx, frames.tsx, phone.tsx, lib.ts and actions.ts.

(sign)

The layout loads Heebo as a body font and forces a dark page background.

(authenticated)

layout.tsx redirects to /login without a session, prefetches the session and the organization list into a HydrationBoundary, and mounts SessionProvider, ActiveOrganizationProvider, ConfirmationAlertProvider and UnsavedChangesProvider.

(authenticated)/(main)

(main)/layout.tsx is a gate with no UI. In order it redirects to:
  1. /login when there is no session.
  2. /set-password when password login is enabled and the user has no credential account.
  3. /onboarding when onboarding is enabled and not complete.
  4. /new-organization when requireOrganization is on and the user has none. It is off in packages/auth/config.ts.
  5. /choose-plan when requireActiveSubscription is on and there is no active plan. It is off in packages/payments/config.ts.

(main)/(account)

Layout: OrgTheme and AppWrapper, themed with the active (or first) organization’s branding. admin/layout.tsx redirects anyone whose session.user.role is not admin back to /. next.config.ts redirects /settings to /settings/general and /admin to /admin/overview.

(main)/(organizations)/[organizationSlug]

layout.tsx loads the organization with getActiveOrganization(slug) and returns notFound() when the user is not a member. It prefetches the organization into its own HydrationBoundary, loads the studio’s branding and calendar flag with getStudioAppearance, and renders OrgTheme and AppWrapper. error.tsx is the error boundary for the whole studio area. /{slug}/settings redirects to /{slug}/settings/general in next.config.ts. loading.tsx files exist for clients, forms, templates, templates/[id]/edit, workboard and the trainee program editor. They render skeletons from RouteSkeleton.tsx.

Reserved slugs

A studio slug is the first URL segment, so it must never collide with a real route. packages/auth/config.ts lists forbiddenOrganizationSlugs: new-organization, admin, settings, ai-demo, organization-invitation, chatbot. Slugs are generated by the backend through orpcClient.organizations.generateSlug.

api/

Route handlers are covered in Route handlers. In short:

Rewrites and redirects

From next.config.ts:
  • beforeFiles rewrite: /trainee-preview to /trainee-preview/index.html. Without it the path would match [organizationSlug].
  • Development only rewrites: /mkt/:path* and /mkt-assets/:path* to the marketing dev server.
  • Permanent redirects: /settings, /:organizationSlug/settings and /admin, as listed above.