{"owner":"TanStack","repo":"router","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":2762,"categories":["root-instruction","mcp-config","marketplace","plugin-manifest","cursor-rule"],"hasMcp":true,"mcpConfig":{"mcpServers":{"router":{"command":"npx","args":["-y","@modelcontextprotocol/server-router"]}}},"found":["AGENTS.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json",".cursorrules (tanstack-router.mdc)"],"skills":{"AGENTS.md":"# AGENTS.md\n\n## Scope\n\n- Read applicable nested `AGENTS.md` files before editing or testing a subtree.\n- Shared routing belongs in `packages/router-core`; check React, Solid, and Vue bindings for shared changes. Shared Start runtime/build logic lives in `packages/start-*-core`.\n\n## Work and validation\n\n- Start bug fixes with a failing regression test that uses only public APIs to reproduce and assert user- or developer-visible behavior. Do not manufacture bugs by mutating internals. Establish whether real usage can reach the failing state before adding runtime handling; simplify handling of states proven unreachable.\n- When removing an API, option, or behavior, delete its tests. Never add tests that assert the removed thing is gone, such as `not.toHaveProperty('oldName')`, a type error for the old call, or a runtime throw.\n- For suspected dependency issues, verify the upstream root cause, then propose an upstream fix to the user, including for other `@tanstack/*` packages. **Never implement a workaround in this repository unless the user explicitly authorizes it.**\n- During debugging/prototyping, keep fixes aligned with the PR's intended architecture. If making a test pass requires another flag, counter, copied deadline, or duplicate completion authority, stop and consolidate state and ownership. Remove superseded paths instead of accumulating patches and bundle growth.\n- Use Node from `.nvmrc` and pnpm from root `package.json`. Install at the root with `CI=1 pnpm install --frozen-lockfile`.\n- For sandbox-blocked registry/store access, escalate the same command; report the blocker if unavailable. Do not change stores, delete dependencies/lockfiles, use `--force`/`--ignore-scripts`, or weaken workspace trust/build policies to bypass it.\n- Never manually edit `pnpm-lock.yaml` or any `routeTree.gen.ts`. Regenerate the lockfile with `pnpm install --no-frozen-lockfile` after intentional dependency changes; regenerate route trees through app builds/dev servers or the generator fixture harness.\n- Always use control-flow braces. Run `pnpm format` before validation.\n- Use Nx: workspace imports consume built packages, so direct runners can test stale dependencies. Inspect resolved targets; some are inferred.\n\n```sh\nCI=1 NX_DAEMON=false pnpm nx run <project>:<target> --outputStyle=stream --skipRemoteCache\n```\n\n- Run one Nx command at a time. For a ~20-second startup/graph stall, stop, run `pnpm nx reset`, and retry once, then escalate. Do not apply that timeout to running tests.\n- For code changes, run affected packages' `test:unit`, `test:types`, and `test:eslint` where available, including affected consumers; use `test:e2e` for browser/app behavior and `test:build` for exports/build changes. Root `pnpm test` includes the full e2e suite. Published-code changes require `pnpm changeset`.\n\n## Runtime rules\n\n- Import `isServer` from `@tanstack/router-core/isServer`. Conditional exports select: `development` → `undefined`; server (`workerd`, `worker`, `deno`, `node`, `bun`) → `true` except `NODE_ENV=test` → `undefined`; browser/fallback → `false`. `development` wins; `NODE_ENV=development` alone does not select it.\n- Keep `isServer ?? router.isServer` directly in each branch condition for dead-code elimination; negate the whole expression for client branches. Never extract it into a variable (e.g. `const serverRendering = isServer ?? router.isServer`) or helper. Without a router, inline `isServer ?? typeof window === 'undefined'` (or the existing `document` check). Keep the constant first and use `??`, never `||`.\n- **Never create UI/router reactivity on the server, including development/tests.** Branch before reactive setup; use direct reads and core non-reactive stores. Required transport listeners are allowed only with request-scoped lifetimes and cleanup.\n- Shared route definitions/build metadata must not acquire request/user data. Keep it on the request's Router, context, or QueryClient.\n- HMR can replace code while caches and pending work survive. Invalidate derived state or bypass caching in development; reject stale async results while preserving intentional HMR identities/state.\n- Gate developer diagnostics and message construction with direct `process.env.NODE_ENV !== 'production'` checks. Preserve required validation/throws in production (e.g. detailed development error, compact `invariant()` failure). `!== 'development'` also enables the guarded code in tests; preserve existing dev-server mode gates.\n\n## Performance and final bundle pass\n\n- For runtime/memory changes, compare identical baseline/candidate workloads using the relevant [benchmark guide](benchmarks/AGENTS.md): client navigation, Start SSR, or memory. Add coverage for unmeasured mechanisms.\n- **Last phase for every change affecting emitted client JavaScript**, including core/build transforms: complete the full [bundle-size-optimization skill](.agents/skills/bundle-size-optimization/SKILL.md) after correctness and performance validation. The full workflow is mandatory.\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/plugin.json)",".cursorrules (tanstack-router.mdc)":"You are an expert in TanStack Router v1, React, TypeScript, and type-safe client-side routing.\n\n## Core Principles\n- TanStack Router is 100% type-safe — leverage TypeScript generics for params, search params, and loader data\n- Prefer file-based routing with `@tanstack/router-vite-plugin` for scalability\n- Always define routes with `createFileRoute` or `createRootRoute`\n- Route data loading belongs in `loader` functions, not in component `useEffect`\n- Search params are first-class — always define their schema with Zod for type safety\n\n## File-Based Route Conventions\n```\nsrc/routes/\n  __root.tsx          ← Root layout\n  index.tsx           ← / route\n  posts/\n    index.tsx         ← /posts\n    $postId.tsx       ← /posts/:postId (dynamic)\n    _layout.tsx       ← Layout route (no path segment)\n  _auth/              ← Pathless auth layout group\n    dashboard.tsx\n```\n\n## Route Definition\n```tsx\nexport const Route = createFileRoute('/posts/$postId')({\n  loader: async ({ params }) => fetchPost(params.postId),\n  component: PostComponent,\n  errorComponent: ({ error }) => <ErrorBanner message={error.message} />,\n  pendingComponent: () => <PostSkeleton />,\n})\n\nfunction PostComponent() {\n  const post = Route.useLoaderData()     // type-safe\n  const { postId } = Route.useParams()  // type-safe\n  return <div>{post.title}</div>\n}\n```\n\n## Type-Safe Search Params\n- Always define search params with Zod and `validateSearch`\n- Access with `Route.useSearch()` — never read `window.location.search` directly\n```tsx\nconst searchSchema = z.object({\n  page: z.number().int().min(1).default(1),\n  q: z.string().optional(),\n})\n\nexport const Route = createFileRoute('/search')({\n  validateSearch: searchSchema,\n  component: SearchPage,\n})\n```\n\n## Navigation\n- Use `<Link>` for internal navigation — never `<a href>`\n- Always pass typed `params` and `search` — the compiler will catch mistakes\n```tsx\n<Link to=\"/posts/$postId\" params={{ postId: '123' }}>View Post</Link>\n```\n\n## Loaders + TanStack Query Integration\n```tsx\nexport const Route = createFileRoute('/posts')({\n  loader: ({ context: { queryClient } }) =>\n    queryClient.ensureQueryData(postsQueryOptions()),\n  component: PostsPage,\n})\n```\n\n## Router Context for Dependency Injection\n```tsx\n// __root.tsx\ninterface RouterContext { queryClient: QueryClient; auth: AuthState }\nexport const Route = createRootRouteWithContext<RouterContext>()({ component: RootLayout })\n\n// main.tsx\nconst router = createRouter({ routeTree, context: { queryClient, auth } })\n```\n\n## Auth Guards\n```tsx\nexport const Route = createFileRoute('/_auth/dashboard')({\n  beforeLoad: ({ context }) => {\n    if (!context.auth.isAuthenticated) throw redirect({ to: '/login' })\n  },\n  component: Dashboard,\n})\n```\n\n## Performance\n- Set `defaultPreload: 'intent'` on router for automatic prefetching on hover/focus\n- Use `React.lazy` for route component code splitting\n- Install `@tanstack/router-devtools` and render `<TanStackRouterDevtools />` in development"},"files":{"AGENTS.md":"# AGENTS.md\n\n## Scope\n\n- Read applicable nested `AGENTS.md` files before editing or testing a subtree.\n- Shared routing belongs in `packages/router-core`; check React, Solid, and Vue bindings for shared changes. Shared Start runtime/build logic lives in `packages/start-*-core`.\n\n## Work and validation\n\n- Start bug fixes with a failing regression test that uses only public APIs to reproduce and assert user- or developer-visible behavior. Do not manufacture bugs by mutating internals. Establish whether real usage can reach the failing state before adding runtime handling; simplify handling of states proven unreachable.\n- When removing an API, option, or behavior, delete its tests. Never add tests that assert the removed thing is gone, such as `not.toHaveProperty('oldName')`, a type error for the old call, or a runtime throw.\n- For suspected dependency issues, verify the upstream root cause, then propose an upstream fix to the user, including for other `@tanstack/*` packages. **Never implement a workaround in this repository unless the user explicitly authorizes it.**\n- During debugging/prototyping, keep fixes aligned with the PR's intended architecture. If making a test pass requires another flag, counter, copied deadline, or duplicate completion authority, stop and consolidate state and ownership. Remove superseded paths instead of accumulating patches and bundle growth.\n- Use Node from `.nvmrc` and pnpm from root `package.json`. Install at the root with `CI=1 pnpm install --frozen-lockfile`.\n- For sandbox-blocked registry/store access, escalate the same command; report the blocker if unavailable. Do not change stores, delete dependencies/lockfiles, use `--force`/`--ignore-scripts`, or weaken workspace trust/build policies to bypass it.\n- Never manually edit `pnpm-lock.yaml` or any `routeTree.gen.ts`. Regenerate the lockfile with `pnpm install --no-frozen-lockfile` after intentional dependency changes; regenerate route trees through app builds/dev servers or the generator fixture harness.\n- Always use control-flow braces. Run `pnpm format` before validation.\n- Use Nx: workspace imports consume built packages, so direct runners can test stale dependencies. Inspect resolved targets; some are inferred.\n\n```sh\nCI=1 NX_DAEMON=false pnpm nx run <project>:<target> --outputStyle=stream --skipRemoteCache\n```\n\n- Run one Nx command at a time. For a ~20-second startup/graph stall, stop, run `pnpm nx reset`, and retry once, then escalate. Do not apply that timeout to running tests.\n- For code changes, run affected packages' `test:unit`, `test:types`, and `test:eslint` where available, including affected consumers; use `test:e2e` for browser/app behavior and `test:build` for exports/build changes. Root `pnpm test` includes the full e2e suite. Published-code changes require `pnpm changeset`.\n\n## Runtime rules\n\n- Import `isServer` from `@tanstack/router-core/isServer`. Conditional exports select: `development` → `undefined`; server (`workerd`, `worker`, `deno`, `node`, `bun`) → `true` except `NODE_ENV=test` → `undefined`; browser/fallback → `false`. `development` wins; `NODE_ENV=development` alone does not select it.\n- Keep `isServer ?? router.isServer` directly in each branch condition for dead-code elimination; negate the whole expression for client branches. Never extract it into a variable (e.g. `const serverRendering = isServer ?? router.isServer`) or helper. Without a router, inline `isServer ?? typeof window === 'undefined'` (or the existing `document` check). Keep the constant first and use `??`, never `||`.\n- **Never create UI/router reactivity on the server, including development/tests.** Branch before reactive setup; use direct reads and core non-reactive stores. Required transport listeners are allowed only with request-scoped lifetimes and cleanup.\n- Shared route definitions/build metadata must not acquire request/user data. Keep it on the request's Router, context, or QueryClient.\n- HMR can replace code while caches and pending work survive. Invalidate derived state or bypass caching in development; reject stale async results while preserving intentional HMR identities/state.\n- Gate developer diagnostics and message construction with direct `process.env.NODE_ENV !== 'production'` checks. Preserve required validation/throws in production (e.g. detailed development error, compact `invariant()` failure). `!== 'development'` also enables the guarded code in tests; preserve existing dev-server mode gates.\n\n## Performance and final bundle pass\n\n- For runtime/memory changes, compare identical baseline/candidate workloads using the relevant [benchmark guide](benchmarks/AGENTS.md): client navigation, Start SSR, or memory. Add coverage for unmeasured mechanisms.\n- **Last phase for every change affecting emitted client JavaScript**, including core/build transforms: complete the full [bundle-size-optimization skill](.agents/skills/bundle-size-optimization/SKILL.md) after correctness and performance validation. The full workflow is mandatory.\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/plugin.json)",".cursorrules (tanstack-router.mdc)":"You are an expert in TanStack Router v1, React, TypeScript, and type-safe client-side routing.\n\n## Core Principles\n- TanStack Router is 100% type-safe — leverage TypeScript generics for params, search params, and loader data\n- Prefer file-based routing with `@tanstack/router-vite-plugin` for scalability\n- Always define routes with `createFileRoute` or `createRootRoute`\n- Route data loading belongs in `loader` functions, not in component `useEffect`\n- Search params are first-class — always define their schema with Zod for type safety\n\n## File-Based Route Conventions\n```\nsrc/routes/\n  __root.tsx          ← Root layout\n  index.tsx           ← / route\n  posts/\n    index.tsx         ← /posts\n    $postId.tsx       ← /posts/:postId (dynamic)\n    _layout.tsx       ← Layout route (no path segment)\n  _auth/              ← Pathless auth layout group\n    dashboard.tsx\n```\n\n## Route Definition\n```tsx\nexport const Route = createFileRoute('/posts/$postId')({\n  loader: async ({ params }) => fetchPost(params.postId),\n  component: PostComponent,\n  errorComponent: ({ error }) => <ErrorBanner message={error.message} />,\n  pendingComponent: () => <PostSkeleton />,\n})\n\nfunction PostComponent() {\n  const post = Route.useLoaderData()     // type-safe\n  const { postId } = Route.useParams()  // type-safe\n  return <div>{post.title}</div>\n}\n```\n\n## Type-Safe Search Params\n- Always define search params with Zod and `validateSearch`\n- Access with `Route.useSearch()` — never read `window.location.search` directly\n```tsx\nconst searchSchema = z.object({\n  page: z.number().int().min(1).default(1),\n  q: z.string().optional(),\n})\n\nexport const Route = createFileRoute('/search')({\n  validateSearch: searchSchema,\n  component: SearchPage,\n})\n```\n\n## Navigation\n- Use `<Link>` for internal navigation — never `<a href>`\n- Always pass typed `params` and `search` — the compiler will catch mistakes\n```tsx\n<Link to=\"/posts/$postId\" params={{ postId: '123' }}>View Post</Link>\n```\n\n## Loaders + TanStack Query Integration\n```tsx\nexport const Route = createFileRoute('/posts')({\n  loader: ({ context: { queryClient } }) =>\n    queryClient.ensureQueryData(postsQueryOptions()),\n  component: PostsPage,\n})\n```\n\n## Router Context for Dependency Injection\n```tsx\n// __root.tsx\ninterface RouterContext { queryClient: QueryClient; auth: AuthState }\nexport const Route = createRootRouteWithContext<RouterContext>()({ component: RootLayout })\n\n// main.tsx\nconst router = createRouter({ routeTree, context: { queryClient, auth } })\n```\n\n## Auth Guards\n```tsx\nexport const Route = createFileRoute('/_auth/dashboard')({\n  beforeLoad: ({ context }) => {\n    if (!context.auth.isAuthenticated) throw redirect({ to: '/login' })\n  },\n  component: Dashboard,\n})\n```\n\n## Performance\n- Set `defaultPreload: 'intent'` on router for automatic prefetching on hover/focus\n- Use `React.lazy` for route component code splitting\n- Install `@tanstack/router-devtools` and render `<TanStackRouterDevtools />` in development"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/TanStack/router/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\n## Scope\n\n- Read applicable nested `AGENTS.md` files before editing or testing a subtree.\n- Shared routing belongs in `packages/router-core`; check React, Solid, and Vue bindings for shared changes. Shared Start runtime/build logic lives in `packages/start-*-core`.\n\n## Work and validation\n\n- Start bug fixes with a failing regression test that uses only public APIs to reproduce and assert user- or developer-visible behavior. Do not manufacture bugs by mutating internals. Establish whether real usage can reach the failing state before adding runtime handling; simplify handling of states proven unreachable.\n- When removing an API, option, or behavior, delete its tests. Never add tests that assert the removed thing is gone, such as `not.toHaveProperty('oldName')`, a type error for the old call, or a runtime throw.\n- For suspected dependency issues, verify the upstream root cause, then propose an upstream fix to the user, including for other `@tanstack/*` packages. **Never implement a workaround in this repository unless the user explicitly authorizes it.**\n- During debugging/prototyping, keep fixes aligned with the PR's intended architecture. If making a test pass requires another flag, counter, copied deadline, or duplicate completion authority, stop and consolidate state and ownership. Remove superseded paths instead of accumulating patches and bundle growth.\n- Use Node from `.nvmrc` and pnpm from root `package.json`. Install at the root with `CI=1 pnpm install --frozen-lockfile`.\n- For sandbox-blocked registry/store access, escalate the same command; report the blocker if unavailable. Do not change stores, delete dependencies/lockfiles, use `--force`/`--ignore-scripts`, or weaken workspace trust/build policies to bypass it.\n- Never manually edit `pnpm-lock.yaml` or any `routeTree.gen.ts`. Regenerate the lockfile with `pnpm install --no-frozen-lockfile` after intentional dependency changes; regenerate route trees through app builds/dev servers or the generator fixture harness.\n- Always use control-flow braces. Run `pnpm format` before validation.\n- Use Nx: workspace imports consume built packages, so direct runners can test stale dependencies. Inspect resolved targets; some are inferred.\n\n```sh\nCI=1 NX_DAEMON=false pnpm nx run <project>:<target> --outputStyle=stream --skipRemoteCache\n```\n\n- Run one Nx command at a time. For a ~20-second startup/graph stall, stop, run `pnpm nx reset`, and retry once, then escalate. Do not apply that timeout to running tests.\n- For code changes, run affected packages' `test:unit`, `test:types`, and `test:eslint` where available, including affected consumers; use `test:e2e` for browser/app behavior and `test:build` for exports/build changes. Root `pnpm test` includes the full e2e suite. Published-code changes require `pnpm changeset`.\n\n## Runtime rules\n\n- Import `isServer` from `@tanstack/router-core/isServer`. Conditional exports select: `development` → `undefined`; server (`workerd`, `worker`, `deno`, `node`, `bun`) → `true` except `NODE_ENV=test` → `undefined`; browser/fallback → `false`. `development` wins; `NODE_ENV=development` alone does not select it.\n- Keep `isServer ?? router.isServer` directly in each branch condition for dead-code elimination; negate the whole expression for client branches. Never extract it into a variable (e.g. `const serverRendering = isServer ?? router.isServer`) or helper. Without a router, inline `isServer ?? typeof window === 'undefined'` (or the existing `document` check). Keep the constant first and use `??`, never `||`.\n- **Never create UI/router reactivity on the server, including development/tests.** Branch before reactive setup; use direct reads and core non-reactive stores. Required transport listeners are allowed only with request-scoped lifetimes and cleanup.\n- Shared route definitions/build metadata must not acquire request/user data. Keep it on the request's Router, context, or QueryClient.\n- HMR can replace code while caches and pending work survive. Invalidate derived state or bypass caching in development; reject stale async results while preserving intentional HMR identities/state.\n- Gate developer diagnostics and message construction with direct `process.env.NODE_ENV !== 'production'` checks. Preserve required validation/throws in production (e.g. detailed development error, compact `invariant()` failure). `!== 'development'` also enables the guarded code in tests; preserve existing dev-server mode gates.\n\n## Performance and final bundle pass\n\n- For runtime/memory changes, compare identical baseline/candidate workloads using the relevant [benchmark guide](benchmarks/AGENTS.md): client navigation, Start SSR, or memory. Add coverage for unmeasured mechanisms.\n- **Last phase for every change affecting emitted client JavaScript**, including core/build transforms: complete the full [bundle-size-optimization skill](.agents/skills/bundle-size-optimization/SKILL.md) after correctness and performance validation. The full workflow is mandatory.\n","isInternal":false,"tokens":1069,"sizeBytes":5029},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":194},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":180},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/TanStack/router/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":173},{"name":".cursorrules","path":".cursorrules (tanstack-router.mdc)","rawUrl":"https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/tanstack-router.mdc","title":"Type-safe routing with TanStack Router v1 for React apps, including file-based routing, loaders, search params validation, auth guards, and TanStack Query integration","category":"cursor-rule","format":"markdown","content":"You are an expert in TanStack Router v1, React, TypeScript, and type-safe client-side routing.\n\n## Core Principles\n- TanStack Router is 100% type-safe — leverage TypeScript generics for params, search params, and loader data\n- Prefer file-based routing with `@tanstack/router-vite-plugin` for scalability\n- Always define routes with `createFileRoute` or `createRootRoute`\n- Route data loading belongs in `loader` functions, not in component `useEffect`\n- Search params are first-class — always define their schema with Zod for type safety\n\n## File-Based Route Conventions\n```\nsrc/routes/\n  __root.tsx          ← Root layout\n  index.tsx           ← / route\n  posts/\n    index.tsx         ← /posts\n    $postId.tsx       ← /posts/:postId (dynamic)\n    _layout.tsx       ← Layout route (no path segment)\n  _auth/              ← Pathless auth layout group\n    dashboard.tsx\n```\n\n## Route Definition\n```tsx\nexport const Route = createFileRoute('/posts/$postId')({\n  loader: async ({ params }) => fetchPost(params.postId),\n  component: PostComponent,\n  errorComponent: ({ error }) => <ErrorBanner message={error.message} />,\n  pendingComponent: () => <PostSkeleton />,\n})\n\nfunction PostComponent() {\n  const post = Route.useLoaderData()     // type-safe\n  const { postId } = Route.useParams()  // type-safe\n  return <div>{post.title}</div>\n}\n```\n\n## Type-Safe Search Params\n- Always define search params with Zod and `validateSearch`\n- Access with `Route.useSearch()` — never read `window.location.search` directly\n```tsx\nconst searchSchema = z.object({\n  page: z.number().int().min(1).default(1),\n  q: z.string().optional(),\n})\n\nexport const Route = createFileRoute('/search')({\n  validateSearch: searchSchema,\n  component: SearchPage,\n})\n```\n\n## Navigation\n- Use `<Link>` for internal navigation — never `<a href>`\n- Always pass typed `params` and `search` — the compiler will catch mistakes\n```tsx\n<Link to=\"/posts/$postId\" params={{ postId: '123' }}>View Post</Link>\n```\n\n## Loaders + TanStack Query Integration\n```tsx\nexport const Route = createFileRoute('/posts')({\n  loader: ({ context: { queryClient } }) =>\n    queryClient.ensureQueryData(postsQueryOptions()),\n  component: PostsPage,\n})\n```\n\n## Router Context for Dependency Injection\n```tsx\n// __root.tsx\ninterface RouterContext { queryClient: QueryClient; auth: AuthState }\nexport const Route = createRootRouteWithContext<RouterContext>()({ component: RootLayout })\n\n// main.tsx\nconst router = createRouter({ routeTree, context: { queryClient, auth } })\n```\n\n## Auth Guards\n```tsx\nexport const Route = createFileRoute('/_auth/dashboard')({\n  beforeLoad: ({ context }) => {\n    if (!context.auth.isAuthenticated) throw redirect({ to: '/login' })\n  },\n  component: Dashboard,\n})\n```\n\n## Performance\n- Set `defaultPreload: 'intent'` on router for automatic prefetching on hover/focus\n- Use `React.lazy` for route component code splitting\n- Install `@tanstack/router-devtools` and render `<TanStackRouterDevtools />` in development","frontmatter":{"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},"tokens":793,"sizeBytes":3004}],"systemPromptSnippet":"<yakaai_skills repo=\"TanStack/router\">\n<!-- File: AGENTS.md (Tokens: ~1069 | Category: root-instruction) -->\n# AGENTS.md\n\n## Scope\n\n- Read applicable nested `AGENTS.md` files before editing or testing a subtree.\n- Shared routing belongs in `packages/router-core`; check React, Solid, and Vue bindings for shared changes. Shared Start runtime/build logic lives in `packages/start-*-core`.\n\n## Work and validation\n\n- Start bug fixes with a failing regression test that uses only public APIs to reproduce and assert user- or developer-visible behavior. Do not manufacture bugs by mutating internals. Establish whether real usage can reach the failing state before adding runtime handling; simplify handling of states proven unreachable.\n- When removing an API, option, or behavior, delete its tests. Never add tests that assert the removed thing is gone, such as `not.toHaveProperty('oldName')`, a type error for the old call, or a runtime throw.\n- For suspected dependency issues, verify the upstream root cause, then propose an upstream fix to the user, including for other `@tanstack/*` packages. **Never implement a workaround in this repository unless the user explicitly authorizes it.**\n- During debugging/prototyping, keep fixes aligned with the PR's intended architecture. If making a test pass requires another flag, counter, copied deadline, or duplicate completion authority, stop and consolidate state and ownership. Remove superseded paths instead of accumulating patches and bundle growth.\n- Use Node from `.nvmrc` and pnpm from root `package.json`. Install at the root with `CI=1 pnpm install --frozen-lockfile`.\n- For sandbox-blocked registry/store access, escalate the same command; report the blocker if unavailable. Do not change stores, delete dependencies/lockfiles, use `--force`/`--ignore-scripts`, or weaken workspace trust/build policies to bypass it.\n- Never manually edit `pnpm-lock.yaml` or any `routeTree.gen.ts`. Regenerate the lockfile with `pnpm install --no-frozen-lockfile` after intentional dependency changes; regenerate route trees through app builds/dev servers or the generator fixture harness.\n- Always use control-flow braces. Run `pnpm format` before validation.\n- Use Nx: workspace imports consume built packages, so direct runners can test stale dependencies. Inspect resolved targets; some are inferred.\n\n```sh\nCI=1 NX_DAEMON=false pnpm nx run <project>:<target> --outputStyle=stream --skipRemoteCache\n```\n\n- Run one Nx command at a time. For a ~20-second startup/graph stall, stop, run `pnpm nx reset`, and retry once, then escalate. Do not apply that timeout to running tests.\n- For code changes, run affected packages' `test:unit`, `test:types`, and `test:eslint` where available, including affected consumers; use `test:e2e` for browser/app behavior and `test:build` for exports/build changes. Root `pnpm test` includes the full e2e suite. Published-code changes require `pnpm changeset`.\n\n## Runtime rules\n\n- Import `isServer` from `@tanstack/router-core/isServer`. Conditional exports select: `development` → `undefined`; server (`workerd`, `worker`, `deno`, `node`, `bun`) → `true` except `NODE_ENV=test` → `undefined`; browser/fallback → `false`. `development` wins; `NODE_ENV=development` alone does not select it.\n- Keep `isServer ?? router.isServer` directly in each branch condition for dead-code elimination; negate the whole expression for client branches. Never extract it into a variable (e.g. `const serverRendering = isServer ?? router.isServer`) or helper. Without a router, inline `isServer ?? typeof window === 'undefined'` (or the existing `document` check). Keep the constant first and use `??`, never `||`.\n- **Never create UI/router reactivity on the server, including development/tests.** Branch before reactive setup; use direct reads and core non-reactive stores. Required transport listeners are allowed only with request-scoped lifetimes and cleanup.\n- Shared route definitions/build metadata must not acquire request/user data. Keep it on the request's Router, context, or QueryClient.\n- HMR can replace code while caches and pending work survive. Invalidate derived state or bypass caching in development; reject stale async results while preserving intentional HMR identities/state.\n- Gate developer diagnostics and message construction with direct `process.env.NODE_ENV !== 'production'` checks. Preserve required validation/throws in production (e.g. detailed development error, compact `invariant()` failure). `!== 'development'` also enables the guarded code in tests; preserve existing dev-server mode gates.\n\n## Performance and final bundle pass\n\n- For runtime/memory changes, compare identical baseline/candidate workloads using the relevant [benchmark guide](benchmarks/AGENTS.md): client navigation, Start SSR, or memory. Add coverage for unmeasured mechanisms.\n- **Last phase for every change affecting emitted client JavaScript**, including core/build transforms: complete the full [bundle-size-optimization skill](.agents/skills/bundle-size-optimization/SKILL.md) after correctness and performance validation. The full workflow is mandatory.\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/TanStack/router/HEAD/.cursor/mcp.json)\n\n<!-- File: .cursorrules (tanstack-router.mdc) (Tokens: ~793 | Category: cursor-rule) -->\nYou are an expert in TanStack Router v1, React, TypeScript, and type-safe client-side routing.\n\n## Core Principles\n- TanStack Router is 100% type-safe — leverage TypeScript generics for params, search params, and loader data\n- Prefer file-based routing with `@tanstack/router-vite-plugin` for scalability\n- Always define routes with `createFileRoute` or `createRootRoute`\n- Route data loading belongs in `loader` functions, not in component `useEffect`\n- Search params are first-class — always define their schema with Zod for type safety\n\n## File-Based Route Conventions\n```\nsrc/routes/\n  __root.tsx          ← Root layout\n  index.tsx           ← / route\n  posts/\n    index.tsx         ← /posts\n    $postId.tsx       ← /posts/:postId (dynamic)\n    _layout.tsx       ← Layout route (no path segment)\n  _auth/              ← Pathless auth layout group\n    dashboard.tsx\n```\n\n## Route Definition\n```tsx\nexport const Route = createFileRoute('/posts/$postId')({\n  loader: async ({ params }) => fetchPost(params.postId),\n  component: PostComponent,\n  errorComponent: ({ error }) => <ErrorBanner message={error.message} />,\n  pendingComponent: () => <PostSkeleton />,\n})\n\nfunction PostComponent() {\n  const post = Route.useLoaderData()     // type-safe\n  const { postId } = Route.useParams()  // type-safe\n  return <div>{post.title}</div>\n}\n```\n\n## Type-Safe Search Params\n- Always define search params with Zod and `validateSearch`\n- Access with `Route.useSearch()` — never read `window.location.search` directly\n```tsx\nconst searchSchema = z.object({\n  page: z.number().int().min(1).default(1),\n  q: z.string().optional(),\n})\n\nexport const Route = createFileRoute('/search')({\n  validateSearch: searchSchema,\n  component: SearchPage,\n})\n```\n\n## Navigation\n- Use `<Link>` for internal navigation — never `<a href>`\n- Always pass typed `params` and `search` — the compiler will catch mistakes\n```tsx\n<Link to=\"/posts/$postId\" params={{ postId: '123' }}>View Post</Link>\n```\n\n## Loaders + TanStack Query Integration\n```tsx\nexport const Route = createFileRoute('/posts')({\n  loader: ({ context: { queryClient } }) =>\n    queryClient.ensureQueryData(postsQueryOptions()),\n  component: PostsPage,\n})\n```\n\n## Router Context for Dependency Injection\n```tsx\n// __root.tsx\ninterface RouterContext { queryClient: QueryClient; auth: AuthState }\nexport const Route = createRootRouteWithContext<RouterContext>()({ component: RootLayout })\n\n// main.tsx\nconst router = createRouter({ routeTree, context: { queryClient, auth } })\n```\n\n## Auth Guards\n```tsx\nexport const Route = createFileRoute('/_auth/dashboard')({\n  beforeLoad: ({ context }) => {\n    if (!context.auth.isAuthenticated) throw redirect({ to: '/login' })\n  },\n  component: Dashboard,\n})\n```\n\n## Performance\n- Set `defaultPreload: 'intent'` on router for automatic prefetching on hover/focus\n- Use `React.lazy` for route component code splitting\n- Install `@tanstack/router-devtools` and render `<TanStackRouterDevtools />` in development\n</yakaai_skills>"}