Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ By creating a `.cursorrules` file in your project's root directory, you can leve
- [React (Redux, TypeScript)](./rules/react-redux-typescript-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with Redux and TypeScript integration.
- [React (MobX)](./rules/react-mobx-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with MobX integration.
- [React (React Query)](./rules/react-query-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with React Query integration.
- [React (TanStack Router)](./rules/tanstack-router-react-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with TanStack Router v1, including file-based routing, type-safe search params, loaders, and auth guards.
Comment on lines 181 to +184
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Reorder entries alphabetically within the State Management category.

The State Management section entries should be in alphabetical order. Currently, the order is Redux → MobX → React Query → TanStack Router. The correct alphabetical order should be: MobX → React Query → Redux → TanStack Router.

As per coding guidelines, "Maintain alphabetical order within each category in the README.md file."

📝 Proposed reordering
 ### State Management
 
+- [React (MobX)](./rules/react-mobx-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with MobX integration.
+- [React (React Query)](./rules/react-query-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with React Query integration.
 - [React (Redux, TypeScript)](./rules/react-redux-typescript-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with Redux and TypeScript integration.
-- [React (MobX)](./rules/react-mobx-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with MobX integration.
-- [React (React Query)](./rules/react-query-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with React Query integration.
 - [React (TanStack Router)](./rules/tanstack-router-react-cursorrules-prompt-file/.cursorrules) - Cursor rules for React development with TanStack Router v1, including file-based routing, type-safe search params, loaders, and auth guards.
🧰 Tools
🪛 LanguageTool

[style] ~183-~183: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...t development with MobX integration. - [React (React Query)](./rules/react-query-curs...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~184-~184: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...opment with React Query integration. - [React (TanStack Router)](./rules/tanstack-rou...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 181 - 184, Reorder the four State Management list
items so they are alphabetically sorted by their visible titles: move "React
(MobX)" and "React (React Query)" before "React (Redux, TypeScript)" so the
final order reads "React (MobX)", "React (React Query)", "React (Redux,
TypeScript)", "React (TanStack Router)"; update the block containing the link
lines for "React (Redux, TypeScript)", "React (MobX)", "React (React Query)",
and "React (TanStack Router)" accordingly.


### Database and API

Expand Down
99 changes: 99 additions & 0 deletions rules-new/tanstack-router.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
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"]
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

globs is an array here, but rules-new/*.mdc files use a single string value for globs (see rules-new/react.mdc:3, rules-new/typescript.mdc:3). For consistency (and to avoid any tooling expecting a string), change this to the same string format.

Suggested change
globs: ["src/routes/**/*", "src/routeTree.gen.ts", "app.config.ts"]
globs: "{src/routes/**/*,src/routeTree.gen.ts,app.config.ts}"

Copilot uses AI. Check for mistakes.
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
Comment on lines +23 to +26
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This route-tree example calls _auth/ a pathless group, but the auth-guard snippet below uses createFileRoute('/_auth/dashboard'). Align the docs so the directory naming and the route path examples reflect the same convention.

Copilot uses AI. Check for mistakes.
```

## 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
Comment on lines +1 to +99
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify that the two .mdc files are duplicates

echo "=== Comparing file sizes ==="
ls -lh rules-new/tanstack-router.mdc rules/tanstack-router-react-cursorrules-prompt-file/tanstack-router.mdc

echo -e "\n=== Computing checksums ==="
md5sum rules-new/tanstack-router.mdc rules/tanstack-router-react-cursorrules-prompt-file/tanstack-router.mdc

echo -e "\n=== Checking for differences ==="
diff rules-new/tanstack-router.mdc rules/tanstack-router-react-cursorrules-prompt-file/tanstack-router.mdc && echo "Files are identical" || echo "Files differ"

Repository: PatrickJS/awesome-cursorrules

Length of output: 554


Remove duplicate file.

This file is an exact duplicate of rules/tanstack-router-react-cursorrules-prompt-file/tanstack-router.mdc. The rules-new/ directory doesn't follow the repository's established structure pattern of rules/[name]-cursorrules-prompt-file/.

Delete rules-new/tanstack-router.mdc and retain only the properly organized version.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rules-new/tanstack-router.mdc` around lines 1 - 99, Delete the duplicate
tanstack-router.mdc file in the rules-new folder: remove the file whose content
begins "Type-safe routing with TanStack Router v1..." (the duplicate of the
canonical
rules/tanstack-router-react-cursorrules-prompt-file/tanstack-router.mdc), and
ensure no other references or imports point to this removed file so only the
canonical tanstack-router.mdc remains in the repository.

170 changes: 170 additions & 0 deletions rules/tanstack-router-react-cursorrules-prompt-file/.cursorrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
You are an expert in TanStack Router, React, TypeScript, and modern type-safe client-side routing.

# TanStack Router + React Guidelines

## Core Philosophy
- TanStack Router is 100% type-safe — leverage TypeScript generics for route params, search params, and loader data
- Prefer file-based routing for scalability; use code-based routing only for highly dynamic use cases
- Always define routes with `createFileRoute` or `createRootRoute` — never use plain objects
- Route data loading belongs in `loader` functions, not in component `useEffect`
- Search params are first-class citizens — define their schema with Zod or Valibot for validation and type inference

## Project Setup
- Use `@tanstack/react-router` with Vite and the `@tanstack/router-vite-plugin` for file-based routing
- Enable `routeTree.gen.ts` auto-generation — never manually edit this file
- Structure routes under `src/routes/` directory
- Root layout goes in `src/routes/__root.tsx`
- Use `src/routes/index.tsx` for the home/index route

## File-Based Route Conventions
```
src/routes/
__root.tsx ← Root layout (wraps all routes)
index.tsx ← / route
about.tsx ← /about route
posts/
index.tsx ← /posts route
$postId.tsx ← /posts/:postId (dynamic segment)
_layout.tsx ← Layout route (no path segment)
_auth/
login.tsx ← /login (grouped under auth layout)
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the file-based routing example, _auth/login.tsx is annotated as mapping to /login, implying _auth/ is a pathless group. Later in this ruleset you define routes like /_auth/dashboard, which treats _auth as a real path segment. Please pick one convention (pathless group vs actual segment) and update the example paths accordingly so users don’t build the wrong URLs.

Suggested change
login.tsx ← /login (grouped under auth layout)
login.tsx ← /_auth/login (under auth segment)

Copilot uses AI. Check for mistakes.
(admin)/
dashboard.tsx ← /dashboard (pathless group)
```

## Route Definition Patterns
```tsx
// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => {
return fetchPost(params.postId) // fully typed params
},
component: PostComponent,
})

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

## Type-Safe Search Params
- Always define search param schemas using `z.object()` from Zod
- Use `validateSearch` option on route definition
- Access with `Route.useSearch()` — never read raw `window.location.search`
```tsx
import { z } from 'zod'
import { createFileRoute } from '@tanstack/react-router'

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,
})

function SearchPage() {
const { page, q } = Route.useSearch()
// ...
}
```

## Navigation
- Use `<Link>` from `@tanstack/react-router` — never `<a href>` for internal navigation
- Use `useNavigate()` for programmatic navigation
- Always pass typed `params` and `search` to Link — the compiler will catch mistakes
```tsx
import { Link, useNavigate } from '@tanstack/react-router'

// Declarative
<Link to="/posts/$postId" params={{ postId: '123' }}>View Post</Link>

// Programmatic
const navigate = useNavigate()
navigate({ to: '/posts/$postId', params: { postId: post.id } })
```

## Loaders & Data Fetching
- Use `loader` for data that must be available before render (no loading spinners for critical data)
- Integrate with TanStack Query by using `ensureQueryData` inside loaders for caching
- Use `staleTime` on loaders to avoid redundant fetches during navigation
- Return plain serializable data from loaders — no class instances
```tsx
export const Route = createFileRoute('/posts')({
loader: ({ context: { queryClient } }) =>
queryClient.ensureQueryData(postsQueryOptions()),
component: PostsPage,
})
```

## Error Handling
- Define `errorComponent` on routes to handle loader or render errors
- Use `notFoundComponent` for 404 states within a route subtree
- Use `pendingComponent` for showing skeletons/spinners during data loading
```tsx
export const Route = createFileRoute('/posts/$postId')({
loader: fetchPost,
errorComponent: ({ error }) => <ErrorBanner message={error.message} />,
pendingComponent: () => <PostSkeleton />,
notFoundComponent: () => <NotFound />,
component: PostDetail,
})
```

## Router Context
- Use router context to inject global dependencies (queryClient, auth, theme) into loaders
- Define context type in `__root.tsx` and pass it when creating the router
```tsx
// __root.tsx
import { createRootRouteWithContext } from '@tanstack/react-router'

interface RouterContext {
queryClient: QueryClient
auth: AuthState
}

export const Route = createRootRouteWithContext<RouterContext>()({
component: RootLayout,
})

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

## Route Guards / Auth
- Use `beforeLoad` for authentication checks — redirect to login if unauthenticated
- Never put auth logic inside components — handle it at the routing layer
```tsx
export const Route = createFileRoute('/_auth/dashboard')({
beforeLoad: ({ context }) => {
if (!context.auth.isAuthenticated) {
throw redirect({ to: '/login' })
}
},
component: Dashboard,
})
Comment on lines +147 to +154
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This auth-guard example uses createFileRoute('/_auth/dashboard'), but earlier in the file _auth/ is presented as a grouping mechanism (e.g., login.tsx -> /login). Align the route path here with the file-based routing convention you intend (either include /_auth everywhere or make _auth pathless and remove it from the route path).

Copilot uses AI. Check for mistakes.
```

## Performance
- Use `preload` on `<Link>` to trigger loader prefetching on hover/focus
- Set `defaultPreload: 'intent'` on the router for automatic preloading
- Use `gcTime` and `staleTime` on loaders to tune cache behavior
- Lazy-load route components with `React.lazy` for code splitting

## DevTools
- Install `@tanstack/router-devtools` and render `<TanStackRouterDevtools />` in development
- Use devtools to inspect route tree, active matches, loader data, and search params

## Testing
- Use `createMemoryHistory` and `createRouter` to create isolated router instances in tests
- Wrap components under test with `<RouterProvider router={testRouter} />`
- Mock loaders by providing fake context values
19 changes: 19 additions & 0 deletions rules/tanstack-router-react-cursorrules-prompt-file/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TanStack Router + React Cursor Rules

Cursor rules for building type-safe React applications with TanStack Router v1, including file-based routing, type-safe search params, loaders, route context, auth guards, and integration with TanStack Query.

## What's covered
- File-based routing conventions and directory structure
- Type-safe params and search param validation with Zod
- Loader-based data fetching (with TanStack Query integration)
- Navigation with `<Link>` and `useNavigate`
- Error, pending, and not-found components
- Router context for dependency injection
- Authentication guards with `beforeLoad`
- Code splitting and preloading strategies
- DevTools setup and testing patterns

## Author
Created by [usm4nhafeez](https://github.com/usm4nhafeez)

Contributed to [awesome-cursorrules](https://github.com/PatrickJS/awesome-cursorrules)
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
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"]
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

globs is defined as a YAML array here, but other rules/ .mdc files consistently use a single comma-separated string (e.g., rules/react-query-cursorrules-prompt-file/react-query-general-best-practices.mdc:3). To match the repo convention (and avoid any consumer expecting a string), consider switching globs to the same string format.

Suggested change
globs: ["src/routes/**/*", "src/routeTree.gen.ts", "app.config.ts"]
globs: src/routes/**/*, src/routeTree.gen.ts, app.config.ts

Copilot uses AI. Check for mistakes.
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
Comment on lines +23 to +26
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file-based routing tree labels _auth/ as a “Pathless auth layout group”, but later examples use /_auth/... paths. Please clarify whether _auth is pathless or a literal path segment and make the directory comment + route paths consistent.

Copilot uses AI. Check for mistakes.
```

## 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
Loading