Documentation
Documentation
Introduction

Getting Started

Getting started
Getting StartedInstallationQuick StartProject Structure

Configuration

Configuration
ConfigurationEnvironment ConfigurationEdge ConfigDatabaseAuth SecretStripeFirebaseStorageGoogle Maps And Cloud Service AccountOAuth ProvidersEmail DeliverySentryFeature Flags

Architecture

Architecture
Architecture OverviewTech StackoRPC MiddlewareDesign Principles

Patterns

Patterns
Code Patterns & ConventionsFeature ModulesError HandlingType Safety

Database

Database
DatabaseSetupSchema DefinitionDatabase OperationsMigrationsCaching
Data Tables

API

oRPCProceduresRoutersoRPC Proxy Setup
APIsOpenAPIREST Endpoints

Auth & Access

AuthenticationConfigurationOAuth ProvidersRolesSession Management
AuthorizationUser RolesPermissions

Routing & i18n

RoutingDeclarative RoutingNavigation
InternationalizationTranslationsLocale Routing

Components & UI

ComponentsButtonsFormsNavigationDialogs
StylesTailwind CSSThemingTypography

Storage

Storage
StorageConfigurationUsageBuckets
Stripe Billing

Extra

Caching

Templates

Templates
Template GuidesCreate New FeatureCreate New PageCreate Database TableCreate oRPC RouterAdd Translations

Development

Development
DevelopmentCommandsAI AgentsBest Practices
Pulling Updates

Routing

Type-safe routing with declarative routes

Overview

This project uses Declarative Routing for type-safe navigation. Routes are automatically generated from page.info.ts files, providing full TypeScript support for navigation.

Routing Structure

Routes are defined in src/routes/ and auto-generated from page.info.ts files:

src/routes/
├── index.ts          # Auto-generated route exports (DO NOT EDIT)
├── makeRoute.tsx     # Route builder utilities
├── routing.ts        # Navigation menus & authorization config
├── hooks.ts          # Route-related hooks
└── utils.ts          # Route utilities

Basic Usage

As a Link

import { PageHome, PageDashboard } from "@/routes";

<PageHome.Link>Go to Home</PageHome.Link>
<PageDashboard.Link>Go to Dashboard</PageDashboard.Link>

Get URL String

const url = PageHome();
const dashboardUrl = PageDashboard();

With Parameters

import { PageUserId } from "@/routes";

// Link with params
<PageUserId.Link id={user.id}>View Profile</PageUserId.Link>

// Or using ParamsLink
<PageUserId.ParamsLink params={{ id: user.id }}>
  View Profile
</PageUserId.ParamsLink>

// Get URL string
const url = PageUserId({ id: user.id });

With Search Params

import { PageSearch } from "@/routes";

<PageSearch.Link search={{ q: "hello", page: 1 }}>
  Search Results
</PageSearch.Link>

const url = PageSearch({}, { q: "hello", page: 1 });

Creating a Page

For complete step-by-step instructions, see the New Page Template.

Quick Example

Create page.info.ts alongside your page.tsx:

// src/app/[locale]/(site)/about/page.info.ts
import { z } from "zod";

export const Route = {
  name: "PageAbout" as const,
  params: z.object({}),
};

The route is automatically available:

import { PageAbout } from "@/routes";

<PageAbout.Link>About Us</PageAbout.Link>

Sitemap Exposure

The sitemap is generated in src/app/sitemap.ts from Routing.Sitemap():

// src/app/sitemap.ts
...Routing.Sitemap().map((route) => ({
  url: absoluteUrl(route),
  alternates: getAlternates(route),
}))

To expose a page in sitemap output, add it to Routing.Sitemap() in src/routes/routing.ts:

// src/routes/routing.ts
Sitemap: () => [
  AllRoutes.PageHome(),
  AllRoutes.PageMyNewPage(), // add your page route
],

Routes not returned by Routing.Sitemap() are not emitted in sitemap.xml by default.

Protected Routes

Routes requiring authentication are defined in src/routes/routing.ts:

PagesRequiringAuth: () => [
  PageSettingsProfile,
  PageDashboard,
  PageAdmin,
],

Routes blocked for authenticated users:

PagesBlockedForAuth: () => [
  PageLogin,
  PageRegister,
  PageForgotPassword,
],

Navigation Configuration

Configure navigation menus in src/routes/routing.ts:

Header Navigation

Header: (role?: UserRole | null) => [
  { route: PageHome },
  { route: PageAbout },
  { route: PagePricing, group: "product" },
],

Dashboard Sidebar

Dashboard: (pathname: string): SidebarMenuGroup[] => [
  {
    groupLabel: "",
    menus: [
      {
        ...routeMenu(PageDashboard, { activePathname: pathname }),
        submenus: [],
      },
    ],
  },
  {
    groupLabel: "content",
    menus: [
      {
        ...routeMenu(PageDashboardProjects, { activePathname: pathname }),
        submenus: [],
      },
    ],
  },
],

Route Icons

Icons are configured in src/routes/config/icons.ts:

import { PageHome, PageDashboard } from "@/routes";

export const Icons: () => Record<string, IconKey> = () => ({
  [PageHome.routeName]: "home",
  [PageDashboard.routeName]: "dashboard",
});

When creating a new page, add an entry to icons.ts to assign an icon.

Route Translations

Page names for navigation are defined in menu.json:

// src/messages/dictionaries/en/menu.json
{
  "links": {
    "PageHome": "Home",
    "PageDashboard": "Dashboard",
    "PageAbout": "About Us"
  }
}

The key must match the name from page.info.ts.

Best Practices

1. Use Typed Routes

// ✅ Good
<PageDashboard.Link>Dashboard</PageDashboard.Link>

// ❌ Bad
<Link href="/dashboard">Dashboard</Link>

2. Add Icons for New Routes

Update icons.ts when creating pages.

3. Update Navigation Configs

Add user-facing pages to navigation menus.

4. Use ParamsLink for Complex Params

<PageUserId.ParamsLink params={{ id: user.id }}>
  View
</PageUserId.ParamsLink>

Next Steps

Declarative Routing

Navigation

New Page Template

On this page

Overview
Routing Structure
Basic Usage
As a Link
Get URL String
With Parameters
With Search Params
Creating a Page
Quick Example
Sitemap Exposure
Protected Routes
Navigation Configuration
Header Navigation
Dashboard Sidebar
Route Icons
Route Translations
Best Practices
1. Use Typed Routes
2. Add Icons for New Routes
3. Update Navigation Configs
4. Use ParamsLink for Complex Params
Next Steps