mcpField
T
tanstack-router

tanstack-router

github.com/marcioaltoe開発063 回インストール今日更新
リポジトリ

tanstack-router について

React と TypeScript のプロジェクト向け TanStack Router スキルです。ルーティング設定、型安全性、データ読み込みに加え、ファイルベースルーティングや検索パラメーター、エラー処理を扱います。

主な機能

  1. 01ファイルベースルーティングとルートツリー生成
  2. 02型安全なナビゲーションとパラメーター
  3. 03ルートローダーとデータの先読み
  4. 04検索パラメーターの検証
  5. 05エラーと 404 の処理
  6. 06コード分割

活用シーン

  1. 01React のファイルベースルート構築
  2. 02型安全な URL 状態の管理
  3. 03ルートのデータ読み込み設定
  4. 04TanStack Query と Router の連携

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/marcioaltoe/skills --skill tanstack-router

インストール後、Claude Code で/tanstack-routerを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
rules/
ctx-route-context.md
err-error-handling.md
load-data-loading.md
load-query-integration.md
nav-navigation.md
org-file-based-routing.md
pre-preloading.md
router-configuration.md
search-params.md
split-code-splitting.md
ts-type-safety.md

詳細

TanStack Router

Version: @tanstack/react-[email protected] Requires: React 18.0+, TypeScript 5.0+, Vite(推奨)

クイックセットアップ

npm install @tanstack/react-router @tanstack/react-router-devtools
npm install -D @tanstack/router-plugin
Vite プラグイン
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
  plugins: [tanstackRouter(), react()],
})
ルートルート
// src/routes/__root.tsx
import { createRootRoute, Outlet } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'

export const Route = createRootRoute({
  component: () => (
    <>
      <Outlet />
      <TanStackRouterDevtools />
    </>
  ),
})
統合 Devtools(複数の TanStack ライブラリと併用する場合に推奨)

Router と Query(またはほかの TanStack ライブラリ)を使用する場合は、個別の Devtools コンポーネントではなく、統合された TanStackDevtools シェルを使用します。

npm install -D @tanstack/react-devtools
// src/routes/__root.tsx
import { createRootRoute, Outlet } from '@tanstack/react-router'
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
import { TanStackDevtools } from '@tanstack/react-devtools'

export const Route = createRootRoute({
  component: () => (
    <>
      <Outlet />
      <TanStackDevtools
        config={{ position: 'bottom-right' }}
        plugins={[
          { name: 'TanStack Router', render: <TanStackRouterDevtoolsPanel /> },
          // Add more plugins: Query, etc.
        ]}
      />
    </>
  ),
})

TanStackDevtools 内に埋め込む場合は、*Panel バリアント(TanStackRouterDevtoolsPanel、ReactQueryDevtoolsPanel)を使用します。

ルーターの作成と型登録
// src/router.tsx
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'

export const router = createRouter({ routeTree })

// Register router type for global inference
declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router
  }
}
エントリーポイント
// src/main.tsx
import { RouterProvider } from '@tanstack/react-router'
import { router } from './router'

function App() {
  return <RouterProvider router={router} />
}
ファイル構成
src/routes/
├── __root.tsx              # Root layout (always rendered)
├── index.tsx               # "/" route
├── about.tsx               # "/about" route
├── posts.tsx               # "/posts" layout
├── posts.index.tsx         # "/posts" index
├── posts.$postId.tsx       # "/posts/:postId" dynamic route
├── _auth.tsx               # Pathless layout (auth guard)
├── _auth.dashboard.tsx     # "/dashboard" (wrapped by _auth)
└── (settings)/
    ├── settings.tsx         # Route group
    └── settings.profile.tsx

ルールのカテゴリ

優先度カテゴリルールファイル影響
CRITICAL型安全性rules/ts-type-safety.md実行時エラーを防ぎ、リファクタリングを可能にします
CRITICALファイルベースルーティングrules/org-file-based-routing.md保守しやすいルート構成を実現します
HIGHルーター設定rules/router-configuration.mdプリロード、スクロール、エラーのグローバルなデフォルトを設定します
HIGHデータ読み込みrules/load-data-loading.mdデータ取得を最適化し、ウォーターフォールを防ぎます
HIGHQuery 統合rules/load-query-integration.mdTanStack Query と Router を連携します
HIGH検索パラメーターrules/search-params.md型安全な URL 状態管理を実現します
HIGHエラー処理rules/err-error-handling.mdエラーと 404 を適切に処理します
MEDIUMナビゲーションrules/nav-navigation.md型安全なリンクとプログラムによるナビゲーションを実現します
MEDIUMコード分割rules/split-code-splitting.mdバンドルサイズを削減します
MEDIUMプリロードrules/pre-preloading.md体感パフォーマンスを向上させます
LOWルートコンテキストrules/ctx-route-context.md依存性注入と認証ガードを実現します

重要なルール

必ず行うこと
  • ルーターの型を登録する — @tanstack/react-router のモジュールを Register.router とともに宣言し、グローバルな型推論を有効にします
  • フックで from パラメーターを使用する(useSearch、useParams、useLoaderData)— 現在のルートの正確な型を取得できます
  • 検索パラメーターを検証する — 任意の Standard Schema ライブラリ(Zod、Valibot、Yup、ArkType など)で validateSearch を使用します
  • ファイルベースルーティングを使用する — プラグインにルートツリーを生成させ、手動で管理しないでください
  • データの取得にはローダーを使用する — コンポーネント内ではなく loader で取得します(ウォーターフォールを防ぎ、プリロードを可能にします)
決して行わないこと
  • 型登録を省略しない — 省略すると、すべてのフックが unknown のユニオン型を返します
  • useEffect でデータを取得しない — 代わりに loader または beforeLoad を使用します
  • Link の型チェックなしに文字列パスを使用しない — <Link to="/typo"> はコンパイル時にエラーを検出します
  • コンポーネントに重いロジックを含めない — ローダーはレンダリング前に実行され、プリロードや並列取得を可能にします

主要なパターン

// Auth guard with beforeLoad + redirect
export const Route = createFileRoute('/_auth')({
  beforeLoad: ({ context }) => {
    if (!context.auth.user) {
      throw redirect({ to: '/login', search: { redirect: location.href } })
    }
  },
})

// Search params with Standard Schema (no adapter needed)
import { z } from 'zod'

const searchSchema = z.object({
  page: z.number().default(1),
  sort: z.enum(['newest', 'oldest']).default('newest'),
})

export const Route = createFileRoute('/posts')({
  validateSearch: searchSchema, // Pass schema directly
})

// Loader with ensureQueryData
export const Route = createFileRoute('/posts/$postId')({
  loader: ({ context, params }) =>
    context.queryClient.ensureQueryData(postQueryOptions(params.postId)),
  component: PostComponent,
})

function PostComponent() {
  const post = Route.useLoaderData()
  return <h1>{post.title}</h1>
}

// Code-split with .lazy.tsx
// posts.tsx — keeps loader (critical path)
export const Route = createFileRoute('/posts')({
  loader: () => fetchPosts(),
})

// posts.lazy.tsx — splits component (loaded after)
export const Route = createLazyFileRoute('/posts')({
  component: PostsComponent,
})

コメント