Skip to main content
rule

tanstack-router — Cursor rule: type-safe React routing

A Cursor rule that sets agent conventions for TanStack Router v1: file-based routes, typed params and loader-based data fetching.

Install into Cursor · Manually: put the files in place All methods and platforms ↓
.cursor/rules/tanstack-router.mdc
Open on GitHub

What tanstack-router does

The rule tells the agent how to write client-side routing with TanStack Router v1 in a React app. Routes are declared with createFileRoute or createRootRoute, data loads inside loader instead of useEffect, and search params get a Zod schema through validateSearch. Internal navigation uses <Link>, never <a href>.

It ships with concrete patterns: the src/routes layout with dynamic segments like $postId and pathless groups, typed access via Route.useLoaderData() and Route.useParams(), and a TanStack Query hookup through queryClient.ensureQueryData. Auth guards live in beforeLoad with a redirect, and router context handles dependency injection.

The rule is scoped by globs — src/routes/**/*, src/routeTree.gen.ts, app.config.ts — so it fires on route files rather than the whole codebase. One thing to check before you rely on it: the examples assume file-based routing with @tanstack/router-vite-plugin, so a project with a hand-written route tree will need those snippets adapted.

What it helps with

  • declare a typed route with a dynamic segment
  • validate search params with Zod instead of reading window.location.search
  • move data fetching out of useEffect into a loader
  • guard a section behind auth with a redirect to login
  • wire the router to TanStack Query through context

Example prompts for the agent

  • add a /posts/$postId route with a loader and component
  • set up typed search params for the search page
  • put an auth guard on /_auth/dashboard

How to install tanstack-router

Manually: put the files in place

.cursor/rules/tanstack-router.mdc

Frontmatter: description, globs, alwaysApply

Step by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules

Questions about tanstack-router

How do I install tanstack-router in Cursor?

Create .cursor/rules/tanstack-router.mdc in your project root and paste the rule content into it. Cursor picks it up automatically and applies it to files matching the globs.

What does this rule do?

It sets agent conventions for TanStack Router v1: file-based routing, typed params and loader data, Zod search validation, auth guards, and TanStack Query integration.

When does the rule apply?

It is bound to the globs src/routes/**/*, src/routeTree.gen.ts and app.config.ts, so it triggers on route files rather than the entire project.

Source text

tanstack-router.mdc · CC0-1.0
---
description: "Type-safe routing with TanStack Router v1 for React apps, including file-based routing, loaders, search params validation, auth guards, and TanStack Query integration"
globs: ["src/routes/**/*", "src/routeTree.gen.ts", "app.config.ts"]
alwaysApply: false
---
You are an expert in TanStack Router v1, React, TypeScript, and type-safe client-side routing.

## Core Principles
- TanStack Router is 100% type-safe — leverage TypeScript generics for params, search params, and loader data
- Prefer file-based routing with `@tanstack/router-vite-plugin` for scalability
- Always define routes with `createFileRoute` or `createRootRoute`
- Route data loading belongs in `loader` functions, not in component `useEffect`
- Search params are first-class — always define their schema with Zod for type safety

## File-Based Route Conventions
```
src/routes/
  __root.tsx          ← Root layout
  index.tsx           ← / route
  posts/
    index.tsx         ← /posts
    $postId.tsx       ← /posts/:postId (dynamic)
    _layout.tsx       ← Layout route (no path segment)
  _auth/              ← Pathless auth layout group
    dashboard.tsx
```

## Route Definition
```tsx
export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params }) => fetchPost(params.postId),
  component: PostComponent,
  errorComponent: ({ error }) => <ErrorBanner message={error.message} />,
  pendingComponent: () => <PostSkeleton />,
})

function PostComponent() {
  const post = Route.useLoaderData()     // type-safe
  const { postId } = Route.useParams()  // type-safe
  return <div>{post.title}</div>
}
```

## Type-Safe Search Params
- Always define search params with Zod and `validateSearch`
- Access with `Route.useSearch()` — never read `window.location.search` directly
```tsx
const searchSchema = z.object({
  page: z.number().int().min(1).default(1),
  q: z.string().optional(),
})

export const Route = createFileRoute('/search')({
  validateSearch: searchSchema,
  component: SearchPage,
})
```

## Navigation
- Use `<Link>` for internal navigation — never `<a href>`
- Always pass typed `params` and `search` — the compiler will catch mistakes
```tsx
<Link to="/posts/$postId" params={{ postId: '123' }}>View Post</Link>
```

## Loaders + TanStack Query Integration
```tsx
export const Route = createFileRoute('/posts')({
  loader: ({ context: { queryClient } }) =>
    queryClient.ensureQueryData(postsQueryOptions()),
  component: PostsPage,
})
```

## Router Context for Dependency Injection
```tsx
// __root.tsx
interface RouterContext { queryClient: QueryClient; auth: AuthState }
export const Route = createRootRouteWithContext<RouterContext>()({ component: RootLayout })

// main.tsx
const router = createRouter({ routeTree, context: { queryClient, auth } })
```

## Auth Guards
```tsx
export const Route = createFileRoute('/_auth/dashboard')({
  beforeLoad: ({ context }) => {
    if (!context.auth.isAuthenticated) throw redirect({ to: '/login' })
  },
  component: Dashboard,
})
```

## Performance
- Set `defaultPreload: 'intent'` on router for automatic prefetching on hover/focus
- Use `React.lazy` for route component code splitting
- Install `@tanstack/router-devtools` and render `<TanStackRouterDevtools />` in development

© PatrickJS · CC0-1.0 · PatrickJS/awesome-cursorrules

Similar IDE rules

All IDE rules for Frontend and UI →

From the same set68

typescript-nodejs-nextjs-react-ui-css-cursorrules- A Cursor rule that pins down how the agent writes TypeScript, Next.js App Router, React and Tailwind code. Useful when generated components drift from your conventions. ★ 41,011repo stars typescript-nextjs-supabase-cursorrules-prompt-file A Cursor rule that keeps TypeScript work on Next.js App Router and Supabase consistent: server components first, Shadcn UI, Tailwind. ★ 41,011repo stars typescript-code-convention-cursorrules-prompt-file A Cursor rule that pins down TypeScript code style for Next.js App Router, React, Expo, tRPC and Tailwind projects. Useful when the agent writes code inconsistently. ★ 41,011repo stars tauri-svelte-typescript-guide-cursorrules-prompt-f A Cursor rule that sets how the agent writes desktop apps with Tauri: Svelte on the frontend, TypeScript for types. ★ 41,011repo stars tanstack-query-v5-cursorrules-prompt-file A Cursor rule that tells the agent how to write TanStack Query v5 code: query keys, mutations, optimistic updates, Suspense and prefetching. ★ 41,011repo stars tailwind-react-firebase-cursorrules-prompt-file A Cursor rule that sets conventions for a mobile-first web app built with Tailwind, React and Firebase. ★ 41,011repo stars sveltekit-typescript-guide-cursorrules-prompt-file A Cursor rule that points the agent at Svelte 5, SvelteKit and TypeScript: project structure, runes, state handling. ★ 41,011repo stars svelte A Cursor rule that steers the agent toward Svelte conventions: component structure, reactivity, stores, SvelteKit routing and tests. Useful when the agent writes or edits Svelte code. ★ 41,011repo stars

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor