用途:为 BTST 插件补充 SSG 支持。构建期不存在服务器,route.loader() 发出的 HTTP 请求会静默失败,导致静态页面渲染为空;解决方案是在原始工厂上暴露 prefetchForRoute,直接从数据库向 React Query 播种数据。
主要能力与文件约定:每个插件需提供 api/query-key-defs.ts(共享 key 形状,供 query-keys.ts 与 prefetchForRoute 共用)、api/serializers.ts(setQueryData 前把 Date 转为 ISO 字符串)、api/getters.ts(补充基于 ID 的 getter)、api/plugin.ts(RouteKey 类型、类型化重载、把 prefetchForRoute 接入原始工厂)、api/index.ts(再导出 RouteKey、serializers、PLUGIN_QUERY_KEYS)、query-keys.ts(从 api/query-key-defs.ts 导入判别函数)、client/plugin.tsx(每个 loader catch 块中加入 isConnectionError 警告)。
关键规则:每次 setQueryData 前序列化 Date 为 ISO 字符串;useInfiniteQuery 列表需 { pages: [...], pageParams: [...] } 形状,扁平数组会破坏 hydration;key 构建器统一从 api/query-key-defs.ts 共享,不要在两处硬编码;一次性初始化(如 CMS ensureSynced)在 prefetchForRoute 顶部调用一次,幂等且对并发 SSG 安全。Next.js 中把请求感知路由放在 app/(request)/pages,SSG/ISR 路由放在 app/(static)/pages,两者仍发布 /pages/* URL;可复用的客户端 StackProvider 外壳放在 app/pages/client-layout.tsx,由请求布局(从可信请求头解析 origin)和无头静态布局分别包裹,避免 SSG 变为动态。
已支持 SSG 的插件:Blog 预取 posts、drafts、post、tag、editPost,跳过 newPost;CMS 预取 dashboard、contentList、editContent,跳过 newContent;Form Builder 预取 formList、editForm、submissions,跳过 newForm;Kanban 预取 boards、board,跳过 newBoard;AI Chat 按用户区分,不静态化,全部跳过。
限制与注意:route.loader() 在构建期静默失败,SSG 页面应改用 prefetchForRoute;注意 query key 漂移、无限查询形状错误、Date 未序列化等问题。完整代码模式见 REFERENCE.md。