Skip to content

Routing with TanStack Router

The Jubiloop webapp uses TanStack Router for type-safe, file-based routing.

Overview

We use TanStack Router v1 with:

  • File-based routing in the /src/routes/ directory
  • Automatic code splitting via Vite plugin
  • Type-safe navigation throughout the app
  • Route groups for authentication boundaries

Current Setup

File Structure

src/routes/
├── __root.tsx          # Root layout with auth checks
├── index.tsx           # Home page (/)
├── (public)/           # Public routes (no auth required)
│   ├── sign-in.tsx    # /sign-in
│   └── sign-up.tsx    # /sign-up
└── (auth)/             # Protected routes
    └── dashboard/
        └── route.tsx   # /dashboard

Router Configuration

See src/main.tsx for the router setup with TanStack Query integration.

Documentation

For comprehensive routing documentation, refer to the official TanStack Router docs:

Key Concepts for Jubiloop

Authentication Pattern

We handle authentication in __root.tsx using the beforeLoad hook. See the authentication feature documentation for implementation details.

Route Groups

  • (public) - Routes accessible without authentication
  • (auth) - Routes requiring authentication
typescript
// Use the Link component
import { Link } from '@tanstack/react-router'
// Use the useNavigate hook
import { useNavigate } from '@tanstack/react-router'

Adding a New Route

  1. Create a file in src/routes/ matching the URL path. To make a route protected, place it under (auth)/.

  2. Define the route with createFileRoute. You can add a loader for data fetching:

typescript
// src/routes/(auth)/events/$eventId.tsx
import { createFileRoute } from '@tanstack/react-router'
import { api } from '@/lib/api/setup'

export const Route = createFileRoute('/(auth)/events/$eventId')({
  loader: async ({ params }) => {
    // Replace orgId with actual context — this is illustrative
    return api.client.get(
      `/organizations/${orgId}/events/${params.eventId}`
    )
  },
  component: EventDetailPage,
})

function EventDetailPage() {
  const event = Route.useLoaderData()
  return <div>{event.data.name}</div>
}
  1. No route registration needed — the Vite plugin auto-generates src/routeTree.gen.ts on save.

  2. Navigate using the type-safe Link component or useNavigate hook:

typescript
import { Link } from '@tanstack/react-router'
<Link to="/events/$eventId" params={{ eventId: id }}>View Event</Link>

For comprehensive patterns (search params, nested layouts, code splitting), refer to the TanStack Router documentation.

Built with ❤️ by the Jubiloop team