关于 intlayer
这是面向 Intlayer 国际化开发的指导技能,重点涵盖 Intlayer 9.6 与 TanStack Start。内容强调依赖版本统一、当前 API、路由选择和变更验证。
主要功能
- 01Intlayer 9.6 与 TanStack Start 指引
- 02统一 Intlayer 软件包版本
- 03配置与内容实现指导
- 04本地化路由与 SSR 指南
- 05CLI、CMS、编译器和分析资料
- 06实现变更验证清单
适用场景
- 01在 TanStack Start 应用中集成 Intlayer
- 02跨 Intlayer 版本更新代码
- 03排查本地化路由或 SSR 问题
- 04检查内容、构建和 CLI 变更
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dobroslavradosavljevic/ skills --skill intlayer安装后在 Claude Code 中输入/intlayer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/cli-cms-ai.mdcompiler-compat.mdconfiguration.mdcontent-dictionaries.mdrouting-ssr-seo.mdsetup-tanstack-start.mdsource-map.md详细介绍
Intlayer
在涉及 Intlayer i18n 的工作中使用此技能,尤其是使用 Intlayer 9.6([email protected];API 与 9.5 系列相同)和 TanStack Start(@tanstack/react-start),通过 intlayer + react-intlayer + vite-intlayer 集成时。
将 intlayer / react-intlayer / vite-intlayer(以及每个 @intlayer/* / *-intlayer 包)固定为相同的精确版本(快照版本为 9.6.0)。不要将 9.0–9.4 文档或包与 9.5+ API(useExperiment、build.chunkGrouping、build.dictionariesPreload、CLI --ci、vite-intlayer/nitro-handler)混用。使用 bunx intlayer upgrade(9.5.8+)一起升级这些包。
快照日期:2026-10-01。如果版本有变化,请从 source-map.md 刷新。
工作流
- 更改代码前,先检查本地 Intlayer + Start 的配置:
intlayer、react-intlayer、vite-intlayer、@tanstack/react-start、@tanstack/react-router的包版本(所有 Intlayer 包必须一致)。- 配置:
intlayer.config.ts中的 locales、routing.mode、routing.enableProxy、routing.storage、content.contentDir、dictionary.importMode、dictionary.fill、compiler.enabled、build.optimize/minify/purge/chunkGrouping/dictionariesPreload、editor、analytics、ai、plugins。 - Vite:
intlayer()插件(proxy.ignore、可选的compatCallers)、tanstackStart({ router: { routeFileIgnorePattern } })、Nitro 插件。 - 路由:
src/routes/__root.tsx外壳 +IntlayerProvider,以及带有validatePrefix的src/routes/{-$locale}/布局。 - 内容:
*.content.{ts,tsx,js,json,...}词典和生成的.intlayer/输出。 - 导航:拒绝使用
LocalizedLink、useLocalizedNavigate和其他任何 Link/navigate 包装器——只使用原生 TanStack Router API。
- 如果任务依赖最新行为、9.5 API、CMS/编辑器/分析功能或包版本变化,请刷新文档。从 source-map.md 开始。
- 安装、配置、Vite 插件、提供程序、Nitro 处理程序和 TypeScript 包含项,请参阅 setup-tanstack-start.md。
intlayer.config.ts的配置项(routing、dictionary、compiler、build、editor、analytics、AI、plugins),请参阅 configuration.md。- 内容声明、节点辅助函数、集合/变体、格式化程序和
useIntlayer,请参阅 content-dictionaries.md。 - locale 路由、原生链接/navigate、SSR
getLocale/getIntlayerAsync、SEOhead、站点地图和 404 页面,请参阅 routing-ssr-seo.md。 - CLI、fill、
--ci、CMS、可视化编辑器、实时同步、MCP 和@intlayer/analytics,请参阅 cli-cms-ai.md。 - 编译器提取、包优化/压缩/清除、分块分组/预加载、导入模式、兼容适配器和
syncJSON,请参阅 compiler-compat.md。 - 命令示例优先使用
bun/bunx。优先参考官方 Start 指南,而不是 Next.js 或 Solid Start 文档——但不要照搬 Intlayer 的LocalizedLink/useLocalizedNavigate示例;请改用原生 TanStack RouterLink/useNavigate。
实现判断
- TanStack Start 使用
intlayer+react-intlayer+vite-intlayer。不要安装或复制next-intlayer/next-intlayer/server或solid-intlayer中的 API。没有tanstack-intlayer这个包。不要在 Start 中使用react-intlayer/server的IntlayerServerProvider。 - Next.js 9.4+ 将
IntlayerClientProvider/IntlayerServerProvider合并到了IntlayerProvider。Start 已使用来自react-intlayer的IntlayerProvider。 - 语言环境检测/重定向由 Vite 的
intlayer()代理处理,而不是 TanStack Router 中间件 API。在当前配置类型中,routing.enableProxy默认值为undefined(自动):代理会运行;开发/预览环境仍由 URL 驱动(忽略已存储的语言环境);生产环境则使用完全由存储驱动的重定向。设为true可强制在所有环境中使用由存储驱动的重定向;设为false可禁用代理。 - 生产环境的 SSR 代理是
vite-intlayer/nitro-handler(h3 v2 Web Fetch)。intlayer()/intlayerProxy会通过nitro/vite注入的.nitro属性自动注册它。在 Bun/Deno 上不要使用fromNodeMiddleware(createIntlayerProxyHandler(...))接入代理——这会导致崩溃(event.node未定义)。如果代理在生产环境运行,请将vite-intlayer保留在运行时dependencies中。 - 不要封装 Link/navigate。 不要创建、保留或推荐
LocalizedLink、useLocalizedNavigate,也不要创建任何封装 TanStackLink/useNavigate并注入语言环境的组件/钩子。使用原生Link和useNavigate,并传入完整的to路径(/{-$locale}/...)以及来自getPrefix(locale).localePrefix的params.locale。审查/迁移时,删除现有封装并重写调用处。官方 Start 文档和 Start 模板仍提供了这类封装示例——请忽略这些示例。 - 始终为
.content.*设置routeFileIgnorePattern,避免内容文件被视为路由。 - 根据
routing.mode设置语言环境路由占位符:prefix-no-default使用{-$locale};prefix-all优先使用$locale;no-prefix/search-params则移除占位符。 - 客户端 UI:使用来自
react-intlayer的useIntlayer/useLocale。感知语言环境的格式化器:react-intlayer/format。A/B:使用来自react-intlayer(或react-intlayer/analytics)的useExperiment。服务端函数、head、加载器和非 React 代码:使用来自intlayer的getIntlayerAsync/getLocale。仅当可接受合并所有语言环境的字典时,才使用同步的getIntlayer。在 Start 中始终显式传入语言环境:从 9.5.12 起,省略语言环境时会先解析为请求语言环境(仅使用 Next.js 标头/ Cookie),再解析为已存储的语言环境,最后解析为默认值;在 Provider 外部,这可能导致 SSR 与水合不匹配。 - 路由
head有三种解析模式(参见路由参考)。优先使用getIntlayerAsync。对于对 LCP 敏感的元数据,请在loader中以staleTime: Infinity解析,并在同步的head中读取loaderData。在 9.4+ 中,除非字典非常小,否则不要在head中使用同步的getIntlayer。 - 在
beforeLoad中,通过validatePrefix根据params.locale验证语言环境,而不是从 Cookie/标头中获取(代理已处理请求语言环境)。 - 将
.content.*与功能代码放在一起。对于源码位于src下的 Start 应用,请显式设置content.contentDir(配置默认值为["."],不是 Next.js 风格的./app)。 compiler.enabled默认值为false。可选值:false|true|"build-only"(在开发环境中跳过)。内置代理/编译器/分块/预加载都位于intlayer()中——除非插件顺序有要求,否则不要单独使用intlayerProxy()/intlayerCompiler()/intlayerChunk()/intlayerPreload()。- 对于 HTML 属性(
alt、title、aria-label),请在内容节点上使用.value、.toString()或String(...)。 - 判别符:
plural/enu(数量)、cond(布尔值)、gender、select(任何其他字符串——9.1)。不要使用运行时键索引内容对象(node[status]);应调用node(status),以便编译器进行压缩/清除。 - 集合共用
key+item。变体使用variant: string | object(9.1 将原先的动态记录合并为对象变体)。选择器:{ locale, item, variant }。解析顺序:variant → item。 - 当
editor.enabled为true时,不要启用build.minify(字段重命名会被跳过)。importMode/ minify / purge / chunkGrouping / dictionariesPreload 需要build.optimize(默认值undefined= 仅生产环境)。 - 在 9.5 中,Start 可以使用
dictionary.importMode: "dynamic",因为chunkGrouping(默认值为 true)和dictionariesPreload(默认值为 true)会合并逐字典的瀑布加载。集合/变体仍按需加载。 - CLI:从 9.5.2 起,
intlayer ci <cmd>已移除。请使用bunx intlayer <cmd> --ci,并设置INTLAYER_PROJECT_CREDENTIALS。从 Agent/CI 使用bunx intlayer init和非交互式子命令(init skills、init mcp等);没有终端时,--interactive会失败(9.6)。 - 使用直接导入读取配置值(
import { defaultLocale, locales } from "intlayer");getConfiguration()已弃用(9.5.9)。
验证
优先使用仓库现有的检查。对于有实质影响的 Intlayer + Start 工作,请包含相关子集:
- 类型检查时纳入
.intlayer/**/*.ts,并重新生成路由树。 - 语言环境冒烟测试:默认语言环境(无前缀或带前缀)、其他语言环境、无效前缀 → 重定向至 404、语言环境切换器。
- 导航冒烟测试:应用内链接和程序化导航保留当前语言环境;切换器无需包装组件即可更新
params.locale。 - SSR 冒烟测试:首个 HTML 的
lang/dir、Cookie/Accept-Language代理重定向、服务端函数getLocale+getIntlayerAsync。在目标 Nitro 预设下进行生产代理冒烟测试(如果使用 Node 和 Bun,则两者都要测)。 - Head/元数据冒烟测试:使用
getIntlayerAsync,确保只加载请求的语言环境代码块;如果使用加载器缓存模式,请确认loaderData可选链和staleTime。 - 内容冒烟测试:缺失键、属性字符串渲染、集合/变体/使用时的
plural/enu/select。 - 当
importMode: "dynamic"时进行动态导入冒烟测试:每个路由边界只发起一次内容请求;热导航时不出现 Suspense 闪烁。 - CLI:词典变更时运行
bunx intlayer build和bunx intlayer test(content test的别名)。Monorepo CMS:运行bunx intlayer fill --ci(而非intlayer ci fill)。 - 更改本地化 SEO 路由时进行站点地图/预渲染冒烟测试。
- 如果涉及 CMS/编辑器/分析:检查实时同步、
push/pull、useExperiment/useConversion,以及用于分析归因的editor.clientId。
报告运行了哪些检查、哪些未运行,以及仍存在哪些与版本相关的假设。
评论
支持 Markdown