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 utilitiesBasic 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>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>