tanstack-start について
json-render の仕様から TanStack Start のページとルートを生成・描画する React 統合です。ページデータ、メタデータ、静的パス向けのサーバーヘルパーと、ルートに応じたフォールバック UI を備えています。
主な機能
- 01TanStack Start で json-render ページを描画
- 02ルートパターンとレイアウトの定義
- 03ページデータとメタデータの取得
- 04静的パスの生成
- 05ルートに応じた読み込み・エラー UI
活用シーン
- 01アプリ仕様からページを構築
- 02パラメーター付きルートのデータ取得
- 03動的ページの静的パス生成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vercel-labs/ json-render --skill tanstack-startインストール後、Claude Code で/tanstack-startを入力して読み込まれたか確認します。
詳細
@json-render/tanstack-start
TanStack Start アプリで、json-render 仕様に記述された完全なページまたはルートが必要な場合に、この統合を使用します。
インストール
npm install @json-render/core @json-render/react @json-render/tanstack-start
アプリケーション仕様
生成カタログに、サーバーセーフな組み込み定義を含めます。レンダラーがこれらのコンポーネント実装を提供します。
import { defineCatalog } from "@json-render/core";
import {
schema,
startComponentDefinitions,
} from "@json-render/tanstack-start/server";
const catalog = defineCatalog(schema, {
components: {
...startComponentDefinitions,
Card: cardDefinition,
Shell: shellDefinition,
Navigation: navigationDefinition,
Home: homeDefinition,
Post: postDefinition,
},
actions: {},
});
次に、StartAppSpec と TanStack Router のルートパターンを使用します。
import type { StartAppSpec } from "@json-render/tanstack-start";
export const spec: StartAppSpec = {
metadata: {
title: { default: "Site", template: "%s | Site" },
},
layouts: {
main: {
root: "shell",
elements: {
shell: { type: "Shell", props: {}, children: ["nav", "slot"] },
nav: { type: "Navigation", props: {}, children: [] },
slot: { type: "Slot", props: {}, children: [] },
},
},
},
routes: {
"/": {
layout: "main",
metadata: { title: "Home" },
page: {
root: "home",
elements: {
home: { type: "Home", props: {}, children: [] },
},
},
},
"/posts/$slug": {
layout: "main",
loader: "post",
staticParams: [{ slug: "hello" }],
page: {
root: "post",
elements: {
post: {
type: "Post",
props: { value: { $state: "/post" } },
children: [],
},
},
},
},
},
};
名前付きパラメーターには /posts/$slug、スプラットには /docs/$ を使用します。スプラットのローダーパラメーターは、_splat の下にスラッシュ区切りの文字列として格納されます。RFC 6902 パッチを生成する際は、ルートキーのスラッシュを ~1 としてエスケープしてください。
すべてのレイアウトに Slot 要素が必要です。startComponentDefinitions を通じて Slot と Link を宣言し、利用側が React 実装を登録する必要がないようにしてください。
サーバーヘルパー
import { createStartApp } from "@json-render/tanstack-start/server";
export const { getPageData, getHead, getStaticPaths } = createStartApp({
spec,
loaders: {
post: async ({ slug }) => ({ post: await getPost(slug as string) }),
},
});
状態のマージ順は、アプリケーションの状態、レイアウトの状態、ページの状態、ローダーデータの順です。getHead は、アプリとルートのメタデータを TanStack の meta および links ディスクリプターにマージします。getStaticPaths は、静的ルートと staticParams を持つ動的ルートを含めます。TanStack Start のトップレベルの pages プラグインオプションには、これらの文字列を { path } オブジェクトに変換して渡してください。ローダーパラメーターは URL デコードされますが、生成されるパスでは staticParams の値が URL エンコードされます。ルートマッチングでは末尾のスラッシュを任意として扱い、エンコード済みまたはデコード済みのパス名表現を受け入れるため、ローダーデータとメタデータは同じ静的ルートを解決します。
ルートの接続
import { createFileRoute, notFound } from "@tanstack/react-router";
import {
PageRenderer,
StartErrorBoundary,
StartLoading,
StartNotFound,
} from "@json-render/tanstack-start";
import { getHead, getPageData } from "@/lib/json-app";
export const Route = createFileRoute("/$")({
loader: async ({ location }) => {
const data = await getPageData({ pathname: location.pathname });
if (!data) throw notFound();
return data;
},
head: ({ match }) => getHead({ pathname: match.pathname }),
component: () => <PageRenderer {...Route.useLoaderData()} />,
pendingComponent: StartLoading,
errorComponent: StartErrorBoundary,
notFoundComponent: StartNotFound,
});
TanStack Router のローダーはサーバーとクライアントの両方で実行されます。仕様ファクトリーまたは名前付きローダーが認証情報、データベースクライアント、あるいはサーバー専用のインポートを使用する場合は、getPageData と getHead を TanStack Start の createServerFn でラップしてください。そのサーバーコードを同形ルートローダーに直接インポートしないでください。
ルートプロバイダー
ルートルートの Outlet を StartAppProvider でラップします。HeadContent をレンダリングして、getHead のメタデータをドキュメントに反映させてください。
import {
createRootRoute,
HeadContent,
Outlet,
Scripts,
} from "@tanstack/react-router";
import { StartAppProvider } from "@json-render/tanstack-start";
import { spec } from "@/lib/spec";
export const Route = createRootRoute({
component: () => (
<html lang="en">
<head>
<HeadContent />
</head>
<body>
<StartAppProvider
registry={registry}
handlers={handlers}
spec={spec}
>
<Outlet />
</StartAppProvider>
<Scripts />
</body>
</html>
),
});
TanStack Router の pendingComponent、errorComponent、notFoundComponent オプションには、それぞれ StartLoading、StartErrorBoundary、StartNotFound を使用します。StartAppProvider に spec を渡すと、各コンポーネントはマッチしたルートに対応するフォールバックを選択します。明示的なフォールバックプロパティは、その参照より優先されます。名前付き $computed 実装は、StartAppProvider.functions を通じて渡してください。デフォルトのエラーバウンダリーはルーターを無効化し、ユーザーが 再試行 を選択すると、失敗したローダーを再実行します。
React コンポーネントは @json-render/tanstack-start からインポートしてください。schema、createStartApp、matchRoute、resolveMetadata、および静的パスヘルパーは @json-render/tanstack-start/server からインポートしてください。