关于 tanstack-start
用于在 TanStack Start 中根据 json-render 规范生成并渲染完整页面与路由的 React 集成。它提供页面数据、元数据和静态路径服务端辅助函数,以及按路由匹配的回退界面。
主要功能
- 01在 TanStack Start 中渲染 json-render 页面
- 02定义路由模式和布局
- 03加载页面数据与元数据
- 04生成静态路径
- 05提供按路由匹配的加载与错误界面
适用场景
- 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 的动态路由。将其字符串转换为 { path } 对象,以用于 TanStack Start 顶层的 pages 插件选项。加载器参数会进行 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 中;不要将该服务器端代码直接导入同构路由加载器。
根 Provider
使用 StartAppProvider 包装根路由的 Outlet。渲染 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>
),
});
将 StartLoading、StartErrorBoundary 和 StartNotFound 用作 TanStack Router 的 pendingComponent、errorComponent 和 notFoundComponent 选项。StartAppProvider 接收 spec 时,每个组件都会选择匹配路由对应的回退组件。显式回退属性会覆盖该查找结果。通过 StartAppProvider.functions 传入命名的 $computed 实现。默认错误边界会使路由器缓存失效,并在用户选择重试时重新运行失败的加载器。
从 @json-render/tanstack-start 导入 React 组件。从 @json-render/tanstack-start/server 导入 schema、createStartApp、matchRoute、resolveMetadata 和静态路径辅助函数。