HyperSaaS
FrontendRouting

Overview

App Router structure with route groups and nested layouts.

HyperSaaS uses Next.js App Router with route groups to separate public, authenticated, and dashboard areas — each with its own layout and navigation.

Route Architecture

src/app/
├── layout.tsx               # Root: fonts, theme, toaster
├── (marketing)/             # Public: header + footer
│   ├── layout.tsx
│   ├── page.tsx             # /
│   ├── pricing/             # /pricing
│   ├── features/            # /features
│   ├── blog/                # /blog, /blog/[slug]
│   └── ...
├── (auth)/                  # Minimal: no nav
│   ├── layout.tsx
│   ├── login/               # /login
│   ├── register/            # /register
│   └── ...
├── (dashboard)/             # Protected: sidebar + breadcrumbs
│   └── dashboard/
│       ├── layout.tsx
│       └── workspaces/
│           └── [workspaceId]/
│               ├── layout.tsx   # Sidebar with workspace context
│               ├── chat/
│               ├── documents/
│               ├── knowledge-bases/
│               ├── teams/
│               └── settings/
├── (workspaces)/            # Workspace list
├── (invitations)/           # Invitation acceptance
├── (chats)/                 # Public shared chats
└── api/                     # API route handlers

Layout Hierarchy

Each route group provides its own layout, and they don't interfere with each other:

Root Layout (fonts, theme, toaster)

    ├── Marketing Layout (header, footer, session provider)

    ├── Auth Layout (minimal wrapper)

    └── Dashboard Layout
        └── Workspace Layout (sidebar, breadcrumbs, auth check)
            └── Chat Layout (flex container, overflow control)

URL Structure

RoutePageAuth
/Home (marketing)No
/pricingPricing pageNo
/featuresFeatures pageNo
/blogBlog listingNo
/blog/[slug]Blog postNo
/loginLogin formNo
/registerRegistration formNo
/dashboardWorkspace listYes
/dashboard/workspaces/[id]Workspace homeYes
/dashboard/workspaces/[id]/chatNew chatYes
/dashboard/workspaces/[id]/chat/[chatId]Chat sessionYes
/dashboard/workspaces/[id]/chat/historyChat historyYes
/dashboard/workspaces/[id]/documentsDocumentsYes
/dashboard/workspaces/[id]/knowledge-basesKnowledge basesYes
/dashboard/workspaces/[id]/knowledge-bases/[kbId]KB detailYes
/dashboard/workspaces/[id]/teamsTeamsYes
/dashboard/workspaces/[id]/teams/[teamId]Team detailYes
/dashboard/workspaces/[id]/settingsWorkspace settingsYes
/dashboard/workspaces/[id]/detailsWorkspace detailsYes
/invitations/accept/[id]Accept invitationYes
/chats/[wsId]/[shareableLink]Shared chat (public)No

Workspace Context Flow

The workspace layout ([workspaceId]/layout.tsx) is the central authority for workspace context:

export default async function WorkspaceLayout({ children, params }) {
  const { workspaceId } = await params;

  // 1. Authenticate
  const user = await getCurrentUserServer();

  // 2. Fetch workspaces
  const workspaces = await getUserWorkspaces();

  // 3. Validate access
  const currentWorkspace = workspaces.find(w => w.id === workspaceId);
  if (!currentWorkspace) redirect("/dashboard");

  // 4. Render shell with sidebar
  return (
    <NextAuthSesionProvider session={session}>
      <SidebarProvider>
        <AppSidebar
          workspaces={workspaces}
          user={user}
          currentWorkspaceId={workspaceId}
        />
        <main>{children}</main>
      </SidebarProvider>
    </NextAuthSesionProvider>
  );
}

All child pages inherit the authenticated user and workspace context.

On this page