Introduction
The Auction Platform uses TanStack Router for type-safe, file-based routing. Routes are organized with layout routes that provide consistent UI patterns across the application.
Route Structure
Routes are defined in the src/routes/ directory using a file-based convention:
Route Directory Structure
routes/
├── __root.tsx # Root layout
├── _with-navbar.tsx # Layout with navbar
│ └── index.tsx # Home page (/)
├── _with-sidebar.tsx # Layout with sidebar
│ └── dashboard.tsx # Dashboard page (/dashboard)
└── _without-navbar.tsx # Layout without navigation
├── login.tsx # Login page (/login)
├── signup.tsx # Signup page (/signup)
└── onboarding.tsx # Onboarding page (/onboarding)
Root Route
The root route defines the base layout and 404 handling:
import { Outlet , createRootRoute } from '@tanstack/react-router'
import * as React from 'react'
import NotFound from '../shared/ui/not found/NotFound'
export const Route = createRootRoute ({
component: RootComponent ,
notFoundComponent () {
return < NotFound />
},
})
function RootComponent () {
return (
< React.Fragment >
< Outlet />
</ React.Fragment >
)
}
The <Outlet /> component renders the matched child route. The root route also defines a custom 404 page.
Layout Routes
With Navbar Layout
The _with-navbar layout adds a navigation bar to public pages:
src/routes/_with-navbar.tsx
import { createFileRoute , Outlet } from '@tanstack/react-router'
import NavBar from '../widgets/Navbar/Navbar'
export const Route = createFileRoute ( '/_with-navbar' )({
component: RouteComponent ,
})
function RouteComponent () {
return (
< div >
< NavBar />
< Outlet />
</ div >
)
}
Routes using this layout:
The _with-sidebar layout provides a dashboard-style interface:
src/routes/_with-sidebar.tsx
import { createFileRoute , Outlet } from '@tanstack/react-router' ;
import Sidebar from '../widgets/Sidebar/Sidebar' ;
export const Route = createFileRoute ( '/_with-sidebar' )({
component: RouteComponent ,
})
function RouteComponent () {
return (
< div
style = { {
height: "100vh" ,
display: "flex" ,
} }
>
< Sidebar />
< main
style = { {
flex: 1 ,
padding: "24px" ,
overflow: "auto" ,
} }
>
< Outlet />
</ main >
</ div >
);
}
Routes using this layout:
/dashboard - Main dashboard
Without Navbar Layout
The _without-navbar layout is used for authentication pages:
src/routes/_without-navbar.tsx
import { createFileRoute , Outlet } from '@tanstack/react-router'
export const Route = createFileRoute ( '/_without-navbar' )({
component: RouteComponent ,
})
function RouteComponent () {
return < div >< Outlet /></ div >
}
Routes using this layout:
/login - Login page
/signup - Signup page
/onboarding - Onboarding page
Route Examples
Home Page
src/routes/_with-navbar/index.tsx
import Home from '@/pages/home/Home'
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute ( '/_with-navbar/' )({
component: Home ,
})
Dashboard Page
src/routes/_with-sidebar/dashboard.tsx
import DashboardMainPannel from '@/features/dashboard/Components/DashboardMainPannel'
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute ( '/_with-sidebar/dashboard' )({
component: RouteComponent ,
})
function RouteComponent () {
return < div >< DashboardMainPannel /></ div >
}
Login Page with Guards
The login route includes authentication guards using beforeLoad:
src/routes/_without-navbar/login.tsx
import { useAuthStore } from '@app/store/auth/auth.store' ;
import AuthLayout from '@features/auth/components/AuthLayout' ;
import { createFileRoute , redirect } from '@tanstack/react-router' ;
export const Route = createFileRoute ( '/_without-navbar/login' )({
beforeLoad : async () => {
const { isAuthenticated , isOnboarded } = useAuthStore . getState ();
// Allow access if not authenticated
if ( ! isAuthenticated ) {
return ;
}
// Redirect to onboarding if authenticated but not onboarded
if ( ! isOnboarded ) {
throw redirect ({ to: "/onboarding" });
}
// Redirect to dashboard if fully authenticated
throw redirect ({ to: "/dashboard" });
},
component : () => < AuthLayout type = "login" /> ,
})
Route guards check authentication state before rendering the component, ensuring users are redirected appropriately.
Route Guards Pattern
TanStack Router’s beforeLoad hook enables route protection:
Check Authentication State
Access the Zustand auth store to check isAuthenticated and isOnboarded.
Apply Business Logic
Determine if the user should access the route or be redirected.
Redirect if Needed
Use throw redirect() to navigate to a different route.
Allow Access
Return nothing or undefined to allow the route to render.
Path Aliases
The application uses TypeScript path aliases for cleaner imports:
{
"compilerOptions" : {
"paths" : {
"@/*" : [ "./src/*" ],
"@app/*" : [ "./src/app/*" ],
"@features/*" : [ "./src/features/*" ],
"@shared/*" : [ "./src/shared/*" ],
"@widgets/*" : [ "./src/widgets/*" ]
}
}
}
Example usage:
import { useAuthStore } from '@app/store/auth/auth.store' ;
import AuthLayout from '@features/auth/components/AuthLayout' ;
import Home from '@/pages/home/Home' ;
Type Safety
TanStack Router generates type definitions automatically:
routeTree.gen.ts - Auto-generated route tree with full type safety
Type-safe route parameters and search params
Compile-time route validation
Don’t manually edit routeTree.gen.ts - it’s automatically generated by TanStack Router.
Navigation
Programmatic Navigation
import { useNavigate } from '@tanstack/react-router' ;
function MyComponent () {
const navigate = useNavigate ();
const goToDashboard = () => {
navigate ({ to: '/dashboard' });
};
return < button onClick = { goToDashboard } > Go to Dashboard </ button > ;
}
Link Component
import { Link } from '@tanstack/react-router' ;
function Navigation () {
return (
< nav >
< Link to = "/" > Home </ Link >
< Link to = "/dashboard" > Dashboard </ Link >
< Link to = "/login" > Login </ Link >
</ nav >
);
}
Best Practices
Group routes with similar layouts using layout routes to reduce duplication.
Use beforeLoad to protect routes and handle authentication/authorization.
Take advantage of TanStack Router’s type-safe navigation and parameters.
Import using path aliases (@app, @features, etc.) for cleaner code.
Architecture Overview Learn about the overall architecture
State Management Understand Zustand stores used in route guards
TanStack Router Docs Official TanStack Router documentation