К основному содержанию
правило

react-tanstack-router-query — правило для Cursor: суть и установка

Настраивает связку TanStack Router v1 и TanStack Query v5 в React-проектах для загрузки данных в роутере без спиннеров ожидания.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/react-tanstack-router-query.mdc
Открыть на GitHub

Что делает react-tanstack-router-query

Правило инструктирует ассистента генерировать архитектуру React SPA на Vite и TypeScript с упором на кэш. Запросы данных выносятся в loader маршрута через queryClient.ensureQueryData, поэтому UI монтируется уже с готовыми данными из кэша. Роутер отвечает за навигацию и состояние URL, а TanStack Query управляет серверным состоянием и мутациями.

Шаблон требует объявлять фабрики queryOptions строго вне компонентов и полностью запрещает фетчинг внутри useEffect. Фильтры и пагинация синхронизируются с параметрами адресной строки через валидацию схем Zod. При мутациях кэш прогревается вручную вызовом setQueryData, после чего вызываются invalidateQueries и мгновенный переход на нужный адрес.

Инструкция применяется только к файлам в src/routes/**/*, src/queries/**/*, src/lib/router.ts и src/lib/queryClient.ts. Для работы строгой типизации необходима декларация модуля через declare module '@tanstack/react-router', иначе TypeScript не сможет проверять пути и параметры роутера.

Какие задачи решает

  • Связать TanStack Router v1 и TanStack Query v5 без лишних экранов загрузки
  • Вынести запросы данных из компонентов в лоадеры маршрутов
  • Синхронизировать параметры URL с ключами кэша запросов
  • Прогревать кэш после мутаций до выполнения перехода

Примеры запросов агенту

  • Создай маршрут src/routes/posts/$postId.tsx с загрузчиком через postQueryOptions и выводом статьи.
  • Добавь список записей с пагинацией через параметры URL и валидацией схемы поиска.
  • Напиши мутацию создания поста, которая обновляет кэш через setQueryData и перенаправляет на страницу записи.

Как установить react-tanstack-router-query

Вручную: положить файлы

.cursor/rules/react-tanstack-router-query.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о react-tanstack-router-query

Как установить react-tanstack-router-query в Cursor?

Создайте файл .cursor/rules/react-tanstack-router-query.mdc в корне проекта и скопируйте в него содержимое правила.

Для каких файлов действует это правило?

Оно срабатывает при редактировании src/routes/**/*, src/queries/**/*, src/lib/router.ts и src/lib/queryClient.ts.

Почему правило запрещает получать данные через useEffect?

Данные запрашиваются в loader до рендеринга страницы с помощью ensureQueryData, поэтому компонент сразу берёт готовый ответ из кэша.

Исходный текст

react-tanstack-router-query.mdc · CC0-1.0
---
description: "React SPA with TanStack Router v1 + TanStack Query v5 — the definitive pattern for zero-loading-spinner routing, type-safe URLs, and cache-first data"
globs: ["src/routes/**/*", "src/queries/**/*", "src/lib/router.ts", "src/lib/queryClient.ts"]
alwaysApply: false
---
You are an expert in React, TanStack Router v1, TanStack Query v5, TypeScript, and Vite.

## Architecture
- TanStack Router: routing, URL state, navigation
- TanStack Query: server state, caching, mutations
- Loader = bridge: prefetches into Query cache before render → zero loading spinners for route data
- Components are pure UI: read from Query cache, trigger mutations

## Setup
```ts
// src/lib/queryClient.ts
export const queryClient = new QueryClient({
  defaultOptions: { queries: { staleTime: 60_000 } },
})

// src/lib/router.ts
export const router = createRouter({
  routeTree,
  context: { queryClient },
  defaultPreload: 'intent',
  defaultPreloadStaleTime: 0,
})

declare module '@tanstack/react-router' {
  interface Register { router: typeof router }
}

// src/main.tsx
<QueryClientProvider client={queryClient}>
  <RouterProvider router={router} context={{ queryClient }} />
</QueryClientProvider>
```

## Query Definitions
```ts
// src/queries/posts.ts
export const postKeys = {
  all: ['posts'] as const,
  detail: (id: string) => [...postKeys.all, 'detail', id] as const,
  list: (f?: PostFilters) => [...postKeys.all, 'list', f] as const,
}

export const postQueryOptions = (id: string) =>
  queryOptions({ queryKey: postKeys.detail(id), queryFn: () => fetchPost(id) })

export const postsQueryOptions = (filters?: PostFilters) =>
  queryOptions({ queryKey: postKeys.list(filters), queryFn: () => fetchPosts(filters) })
```

## Loader + Component (zero loading state)
```tsx
export const Route = createFileRoute('/posts/$postId')({
  loader: ({ context: { queryClient }, params }) =>
    queryClient.ensureQueryData(postQueryOptions(params.postId)),
  component: PostDetail,
})

function PostDetail() {
  const { postId } = Route.useParams()
  const { data: post } = useQuery(postQueryOptions(postId))  // always in cache from loader
  return <h1>{post!.title}</h1>
}
```

## Search Params → Query Key
```tsx
const searchSchema = z.object({ page: z.number().default(1), q: z.string().optional() })

export const Route = createFileRoute('/posts/')({
  validateSearch: searchSchema,
  loader: ({ context: { queryClient }, location: { search } }) =>
    queryClient.ensureQueryData(postsQueryOptions(search)),
  component: PostsList,
})

function PostsList() {
  const search = Route.useSearch()
  const { data } = useQuery(postsQueryOptions(search))
  // ...
}
```

## Mutations
```tsx
const mutation = useMutation({
  mutationFn: createPost,
  onSuccess: (newPost) => {
    queryClient.setQueryData(postKeys.detail(newPost.id), newPost)  // warm cache
    queryClient.invalidateQueries({ queryKey: postKeys.list() })
    navigate({ to: '/posts/$postId', params: { postId: newPost.id } })  // instant — no spinner
  },
})
```

## Hover Prefetching
```tsx
<Link
  to="/posts/$postId"
  params={{ postId: post.id }}
  onMouseEnter={() => queryClient.prefetchQuery(postQueryOptions(post.id))}
>
  {post.title}
</Link>
```

## Key Rules
- Always define `queryOptions` outside components — never inline inside `useQuery()`
- Never use `useEffect` for data fetching — use loaders or `useQuery`
- Search params are the single source of truth for filter/pagination state
- After mutations: `setQueryData` + `invalidateQueries` for instant UI feedback
- `declare module '@tanstack/react-router'` router registration is required for full type safety

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

Похожие правила IDE

Все правила IDE по теме «Фронтенд и UI» →
winui3 официальный github Правило задаёт рекомендации для WinUI 3 и Windows App SDK: от XAML и потоков до окон и MVVM. Пригодится, чтобы Copilot учитывал особенности настольных приложений Windows. ★ 40 451звёзд репо vue официальный github Правило задаёт Copilot стандарты Vue 3: Composition API, <script setup>, реактивность, Pinia и Vue Router. Пригодится, когда агент пишет компоненты в вашем стиле. ★ 40 451звёзд репо tanstack-start-shadcn-tailwind официальный github Правило задаёт Copilot стек TanStack Start, Shadcn/ui и Tailwind CSS и требует валидировать внешние данные через Zod. ★ 40 451звёзд репо tailwind-v4-vite официальный github Правило помогает подключить Tailwind CSS v4 к проекту на Vite через официальный плагин. Пригодится и для новой установки, и при переходе с v3. ★ 40 451звёзд репо svelte официальный github Направляет GitHub Copilot на стандарты Svelte 5 и SvelteKit 2: руны вместо старых сторов, типизация компонентов и безопасная работа с SSR. ★ 40 451звёзд репо power-bi-custom-visuals-development официальный github Правило для GitHub Copilot, которое подсказывает агенту, как писать кастомные визуалы Power BI на React, D3.js и TypeScript. ★ 40 451звёзд репо

Из того же набора234

Весь набор →
react Правило задаёт агенту Cursor соглашения по React: структура компонентов, хуки, состояние, формы и доступность. Пригодится, когда в проекте много .tsx и .jsx и хочется единый стиль. ★ 41 024звёзд репо react-zustand-cursorrules-prompt-file Инструкция для Cursor по работе со стейт-менеджером Zustand в React и TypeScript. Задаёт архитектуру сторов, защищает от лишних ререндеров и отсекает серверный кэш от клиентских данных. ★ 41 024звёзд репо react-typescript-symfony-cursorrules-prompt-file Правило Cursor, которое настраивает ассистента на чистый код в стеке React, TypeScript, PHP, Symfony и Docker. ★ 41 024звёзд репо react-typescript-nextjs-nodejs-cursorrules-prompt- Правило для Cursor задаёт стиль кода на React, TypeScript, Next.js 14 и Node.js: функциональные компоненты, RORO, минимум use client. ★ 41 024звёзд репо react-tanstack-router-query-cursorrules-prompt-file Правило задаёт схему для React SPA: TanStack Router управляет маршрутами, а TanStack Query — серверными данными и кэшем. Пригодится, когда данные маршрута нужно загрузить до показа страницы. ★ 41 024звёзд репо react-styled-components-cursorrules-prompt-file Правило для Cursor, которое задаёт агенту стиль кода на React со styled-components: функциональные компоненты, тема через ThemeProvider, папка styles. ★ 41 024звёзд репо react-router-v7 Задаёт стандарты React Router v7 для маршрутов, загрузчиков, мутаций и типизации в файлах TypeScript и конфигах проекта. ★ 41 024звёзд репо react-redux-typescript-cursorrules-prompt-file Правило задаёт стиль React-кода с Redux и TypeScript: функциональные компоненты, типизированные хуки и структуру проекта. Подключается к Cursor. ★ 41 024звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой