tanstack-router — правило для Cursor: типизированный роутинг в React
Правило для Cursor, которое задаёт агенту стандарты TanStack Router v1: файловые маршруты, типизация параметров и загрузка данных через loader.
.cursor/rules/tanstack-router.mdcЧто делает tanstack-router
Правило описывает, как писать клиентский роутинг на TanStack Router v1 в React-проекте. Агент получает набор принципов: маршруты объявляются через createFileRoute или createRootRoute, данные грузятся в loader, а не в useEffect, поисковые параметры описываются схемой Zod через validateSearch. Для навигации — только <Link>, без <a href>.
Внутри есть готовые шаблоны: структура папки src/routes с динамическими сегментами вида $postId и группами без пути, примеры типизированного доступа к данным через Route.useLoaderData() и Route.useParams(), связка с TanStack Query через queryClient.ensureQueryData. Отдельно разобраны auth-гарды в beforeLoad с редиректом и внедрение зависимостей через контекст роутера.
Правило подключается по globs — src/routes/**/*, src/routeTree.gen.ts, app.config.ts, — поэтому срабатывает только на файлах маршрутов, а не на всём проекте. Учитывайте: шаблоны рассчитаны на файловый роутинг с @tanstack/router-vite-plugin, так что в проекте с ручным деревом маршрутов часть примеров придётся переписывать под себя.
Какие задачи решает
- объявить типизированный маршрут с динамическим сегментом
- описать поисковые параметры схемой Zod и не читать
window.location.search - перенести загрузку данных из
useEffectвloader - закрыть раздел за auth-гардом с редиректом на логин
- связать роутер с TanStack Query через контекст
Примеры запросов агенту
- добавь маршрут /posts/$postId с loader и компонентом
- сделай типизированные поисковые параметры для страницы поиска
- поставь auth-гард на /_auth/dashboard
Как установить tanstack-router
Вручную: положить файлы
.cursor/rules/tanstack-router.mdcВо frontmatter: description, globs, alwaysApply
Вручную: положить файлы
.claude/rules/tanstack-router.mdПоле paths во frontmatter ограничивает файлы: globs из источника → paths
AGENTS.md
Codex читает AGENTS.md: вставьте текст правила туда
Вручную: положить файлы
.github/instructions/tanstack-router.instructions.mdПоле applyTo задаёт, к каким файлам применять: globs из источника → applyTo
Вручную: положить файлы
.devin/rules/tanstack-router.mdВручную: положить файлы
.clinerules/tanstack-router.mdПо шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules
Вопросы о tanstack-router
Как установить tanstack-router в Cursor?
Создайте файл .cursor/rules/tanstack-router.mdc в корне проекта и вставьте в него содержимое правила. Cursor подхватит его автоматически и будет применять к файлам, подходящим под globs.
Что делает это правило?
Задаёт агенту стандарты TanStack Router v1: файловый роутинг, типизация параметров и loader-данных, валидация поисковых параметров через Zod, auth-гарды и интеграция с TanStack Query.
Когда правило применяется?
Оно привязано к globs src/routes/**/*, src/routeTree.gen.ts и app.config.ts, поэтому срабатывает при работе с файлами маршрутов, а не со всем кодом проекта.
Исходный текст
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