浏览文档目录
Agent docs/query/ssr-streaming
contract

配置 Query SSR 与流式恢复

为每个 SSR 请求创建 QueryClient,通过官方 Router 集成脱水与恢复,并明确阻塞和流式查询。

View raw Markdown
CONTRACT

执行契约

适用场景
Router 或 Start 应用要在 SSR 中预取 Query,并自动脱水、恢复或流式发送结果。
不要使用
纯 SPA 或仅客户端数据不需要 SSR 序列化;不要为它们增加服务端恢复复杂度。
前置检查
确认 getRouter 按请求执行、QueryClient 的所有者、关键与非关键查询分类,以及允许进入浏览器载荷的数据字段。
验证结果
用并发用户会话检查缓存隔离,检查 HTML/流载荷不含秘密,并确认 hydrated 查询不会立刻重复请求。
失败模式
跨请求数据串线说明 QueryClient 被提升成模块单例;hydration 后重复请求通常来自 key、实例或 staleTime 不一致。
安全边界
脱水缓存对浏览器可见;先授权再查询,只序列化最小字段,并依赖安全转义的官方集成处理 HTML 上下文。
01

实例所有权

QueryClient 必须创建在 getRouter 内并同时传给 Router Context 与集成函数。不得把带用户数据的 QueryClient 提升成服务端模块单例。SSR 查询设置合理 staleTime,避免恢复后立即因为陈旧状态重复请求。

src/router.tsxtsx
export function getRouter() {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { staleTime: 30_000 } },
  })
  const router = createRouter({ routeTree, context: { queryClient } })
  setupRouterSsrQueryIntegration({ router, queryClient })
  return router
}
02

加载模式

关键数据在 Loader 中 return/await ensureQueryData;允许渐进到达的数据只启动 fetchQuery,不 return 或 await。组件需要参与 SSR 时使用 useSuspenseQuery;普通 useQuery 在 hydration 后才从客户端请求。避免顺序 await 无依赖的查询。

03

载荷审计

只脱水允许浏览器读取的数据,可用 shouldDehydrateQuery 排除明确标记的条目。检查 HTML 与流式载荷不含秘密、服务端字段或其他用户数据;自定义序列化必须处理 HTML 转义,不要直接拼接 JSON.stringify。

PRIMARY SOURCEShttps://tanstack.com/router/latest/docs/integrations/queryhttps://tanstack.com/query/latest/docs/framework/react/guides/ssr