tanstack-start について
TanStack Router を基盤とするフルスタック React フレームワーク、TanStack Start の開発ガイドです。型安全なサーバー関数、SSR、Middleware、デプロイ設定を扱い、現在は RC 段階です。
主な機能
- 01型安全なサーバー関数
- 02SSR とストリーミング
- 03リクエスト Middleware の合成
- 04セッションとルート保護
- 05複数プラットフォームへのデプロイ設定
活用シーン
- 01サーバー側のデータ取得と更新の実装
- 02認証とセッションの追加
- 03SSR またはストリーミングページの構築
- 04API ルートとデプロイ先の設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill tanstack-startインストール後、Claude Code で/tanstack-startを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api-routes.mddeployment.mdelectric-middleware.mderror-handling.mdfile-organization.mdintegration-flows.mdknown-issues.mdllmo.mdlocal-first.mdmiddleware.mdquery-integration.mdroute-protection.mdseo.mdserver-functions.mdssr-and-streaming.md詳細
TanStack Start
TanStack Router を基盤とするフルスタック React フレームワークです。RPC による型安全なサーバー関数、SSR/ストリーミング、ミドルウェアの合成に対応し、Cloudflare Workers、Vercel、Netlify、AWS Lambda などにデプロイできます。
RC: TanStack Start は現在、リリース候補の段階です。安定版 1.0 のリリース前に API が変更される可能性があります。
パッケージ: @tanstack/react-start
クイックリファレンス
| パターン | 用途 |
|---|---|
createServerFn() | GET(デフォルト)— 冪等でキャッシュ可能なデータ取得 |
createServerFn({ method: 'POST' }) | データを変更するミューテーション |
.inputValidator(zodSchema) | ハンドラー実行前の入力検証 |
.handler(async ({ data }) => {}) | 型付き入力データを使ったサーバーサイドのロジック |
getRequest() | ハンドラー/ミドルウェア内で受信した Request 全体にアクセス |
getRequestHeader(name) | 名前を指定して単一のリクエストヘッダーを読み取る |
setResponseHeaders(headers) | 送信レスポンスヘッダーを設定する(キャッシュ、Cookie) |
useServerFn(fn) | 保留状態を使い、コンポーネント用にサーバー関数をラップする |
createMiddleware().server(fn) | 横断的関心事に対応するリクエストミドルウェア |
.middleware([dep]) | 依存関係を指定してミドルウェアを合成する |
next({ context: {} }) | ミドルウェアチェーンを通じて後続にデータを渡す |
createMiddleware({ type: 'function' }) | 入力検証を行う関数レベルのミドルウェア |
createStart() 内の requestMiddleware | すべてのリクエスト(SSR、関数、ルート)に適用するグローバルミドルウェア |
createStart() 内の functionMiddleware | サーバー関数のみに適用するグローバルミドルウェア |
createIsomorphicFn() | 環境ごとに異なる実装を定義する |
createServerOnlyFn() | サーバー専用ユーティリティ — クライアントから呼び出すとクラッシュする |
createClientOnlyFn() | クライアント専用ユーティリティ — サーバーから呼び出すとクラッシュする |
useSession() | 暗号化とセキュアな設定に対応した Cookie ベースのセッション |
session.update() | セッションデータを更新する |
session.clear() | セッションをクリアする(ログアウト) |
beforeLoad | ルート読み込み前に認証を確認する |
_authenticated.tsx | 保護をグループ化するためのパスレスレイアウトルート |
throw redirect({ to: '/login' }) | 戻り先 URL を指定してリダイレクトする |
await ensureQueryData() | 重要なデータのために SSR をブロックする |
prefetchQuery() | フェッチを開始し、SSR をブロックしない |
<Suspense> 境界 | ストリーミングチャンクを定義する |
head: ({ loaderData }) => ({}) | メタタグ、Open Graph、ファビコン |
head.scripts + JSON-LD | LLMO(schema.org)向けの構造化データ |
llms.txt サーバールート | AI システム向けのガイダンスファイル |
headers: () => ({...}) | ルート定義での ISR/cache-control |
server: { handlers: { GET, POST } } | createFileRoute 上の API ルート |
ssr: false | 特定のルートで SSR を無効にする(SPA モード) |
実行境界
| 関数 | 実行場所 | クライアントから呼び出し可能? | 用途 |
|---|---|---|---|
createServerFn() | サーバー | はい(RPC スタブ) | データ取得、ミューテーション |
createServerOnlyFn() | サーバー | いいえ(例外をスロー) | シークレット、DB 接続 |
createClientOnlyFn() | クライアント | 該当なし | localStorage、DOM API |
createIsomorphicFn() | 両方 | 該当なし | 環境ごとの実装 |
デプロイ(Vite プラグイン)
| プラットフォーム | プラグイン | ランタイム |
|---|---|---|
| Cloudflare | @cloudflare/vite-plugin | Workers |
| Netlify | @netlify/vite-plugin-tanstack-start | Node |
| Vercel | nitro/vite (preset: 'vercel') | Node |
| Node.js/Docker | nitro/vite (preset: 'node-server') | Node |
| AWS Lambda | nitro/vite (preset: 'aws-lambda') | Node |
| Bun | nitro/vite (preset: 'bun') | Bun |
| 静的 | nitro/vite (preset: 'static') | なし |
よくある間違い
| 間違い | 修正 |
|---|---|
サーバー関数に .inputValidator() がない | 常に Zod スキーマで検証する |
createServerFn ではなく生の fetch を使う | 型安全性、シリアル化、コード分割が失われます |
| 境界を設けずにサーバー/クライアントコードを混在させる | createServerOnlyFn / createClientOnlyFn を使う |
| すべてのハンドラーで認証を確認する | ミドルウェアの合成または beforeLoad を使う |
| ローダーですべてのデータを待機する | 重要なデータのみを待機し、残りは先読みする |
レンダリング中に Date.now() を使う | ローダーからタイムスタンプを渡す(ハイドレーションの不一致) |
nodejs_compat フラグがない | Cloudflare では wrangler.toml で必須 |
| ミューテーションに GET を使う | 作成/更新/削除には POST を使う |
| 外部 API に Cookie が転送されない | getRequestHeader() または createIsomorphicFn を使う |
ローダーで process.env を使う(両方で実行される) | createServerFn でラップする — ローダーはクライアント側でも実行されます |
| サーバー環境変数が検証されていない | .server.ts ファイルで Zod を使って検証する |
| 認証トークンを localStorage に保存する | useSession を介して HTTP 専用 Cookie を使う |
| 生の DB エラーをクライアントに公開する | 捕捉してユーザー向けのメッセージを返し、詳細をログに記録する |
| コンテンツページに構造化データがない | AI による検出性を高めるため、head.scripts で JSON-LD を追加する |
委任
TanStack Start のサーバー関数、ミドルウェア、SSR/ストリーミング、ルート保護、API ルート、デプロイ設定には、このスキルを使います。ファイルベースルーティング、検索パラメーター、データ読み込みパターンは tanstack-router に委任します。キャッシュ管理、楽観的更新、クエリパターンは tanstack-query に委任します。
tanstack-formスキルが利用できる場合は、フォーム状態管理、検証、フィールドパターンを委任します。local-firstスキルが利用できる場合は、ローカルファーストアーキテクチャの判断と同期エンジンの選定を委任します。electricsqlスキルが利用できる場合は、ElectricSQL のシェイプ、認証設定、書き込みパターンを委任します。tanstack-dbスキルが利用できる場合は、リアクティブコレクション、ライブクエリ、楽観的ミューテーションパターンを委任します。
リファレンス
- サーバー関数 — createServerFn、useServerFn、バリデーション、認証、リクエストコンテキスト、レスポンスヘッダー、ファイルアップロード、ストリーミング、TanStack Query との統合
- ミドルウェア — 合成、関数レベルのミドルウェア、ルートレベルのミドルウェア、グローバルミドルウェア、ロギング、レート制限
- SSR とストリーミング — Suspense、プリレンダリング、ISR、cache-control、ハイブリッド戦略、ハイドレーションの安全性
- ルート保護 — beforeLoad、パスレスレイアウト、セッションセキュリティ、ログイン/ログアウト、ヘッダーの転送、Better Auth
- API ルート — サーバーハンドラー、REST パターン、ルートレベルのミドルウェア、Webhook、ヘルスチェック、サーバー関数とサーバールートの比較
- デプロイ — Vite プラグイン、アダプターの比較、Cloudflare D1/KV/R2 バインディング、Docker、プリレンダリング
- SEO とヘッド管理 — head プロパティ、メタタグ、Open Graph、Twitter Cards、ファビコン、SEO ヘルパー
- LLM 最適化(LLMO) — JSON-LD 構造化データ、schema.org、llms.txt、機械可読エンドポイント、AI 引用パターン
- エラー処理 — 判別可能なユニオン、カスタムエラークラス、ステータスコード、結果型と try-catch の比較
- ファイル構成 — エントリーポイント、プラグイン設定、実行境界、環境変数のバリデーション、.server.ts 規約
- 既知の問題 — 回避策を含む、文書化された 10 件の問題
- Query との統合 — Router+Query のセットアップ、SSR 統合、setupRouterSsrQueryIntegration、DevTools
- 統合フロー — キャッシュ更新を伴うフォーム送信、無限スクロール、ページネーション付きテーブル、認証で保護されたルート、エラー処理
- ローカルファースト統合 — shape プロキシサーバー関数、サーバーベースのデータとローカルファーストのデータの混在、ElectricSQL のデプロイ
- Electric ミドルウェア — shape プロキシ用の認証ミドルウェア、グローバルミドルウェア設定、sendContext、関数レベルのバリデーション