使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
版本历史
- "比较路由 head 函数中元数据字典的静态解析、动态解析与带缓存的动态解析"v9.4.02026/8/25
- "更新 Solid useIntlayer API 用法以直接访问属性"v8.9.02026/5/4
- "针对 Tanstack Start Solid.js 添加"v8.5.12026/3/25
此页面的内容已使用 AI 翻译。
查看英文原文的最新版本如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
使用 Intlayer 翻译您的 Tanstack Start + Solid.js 网站 | 国际化 (i18n)
目录
本指南演示了如何集成 Intlayer,以便在包含 Solid.js 的 Tanstack Start 项目中实现无缝国际化、本地化感知路由、TypeScript 支持以及现代开发实践。
为什么选择 Inlayer 而不是替代品?
与 react-i18next 或 i18next 等主要解决方案相比,Intlayer 是一个附带集成优化的解决方案,例如:
与“react-i18next”或“i18next”等主要解决方案相比,Intlayer是一个具有集成优化的解决方案,例如:
完整的 TanStack Start 覆盖
Intlayer 经过优化,可与 TanStack Start 和 Solid 完美配合,提供多语言路由、站点地图以及扩展国际化 (i18n) 所需的所有功能。
捆绑尺寸
不要将大量 JSON 文件加载到页面中,而只需加载必要的内容。 Intlayer 有助于将捆绑包和页面大小减少多达 50%。
</Accordion>
可维护性
确定应用程序内容的范围有利于大型应用程序的维护。您可以复制或删除单个功能文件夹,而无需承担检查整个内容代码库的精神负担。此外,Intlayer 具有完全类型化 (fully typed),以确保您的内容的准确性。
人工智能代理
共置内容减少大型语言模型 (LLM) 所需的上下文。 Intlayer 还附带了一套工具,例如用于测试缺失翻译的 CLI、LSP、MCP 和 agent skills,使 AI 代理的开发者体验 (DX) 更加流畅。
自动化
使用您选择的法学硕士,通过自动化在 CI/CD 管道中进行翻译,而费用由您的 AI 提供商承担。 Intlayer 还提供了一个编译器来自动提取内容,以及一个网络平台来帮助在后台翻译。
表现
将大量 JSON 文件连接到组件可能会导致性能和反应性问题。 Intlayer 可在构建时 (build time)优化您的内容加载。
无需开发即可扩展
在 Tanstack Start 应用中设置 Intlayer 的分步指南
参见 GitHub 上的应用模板。
创建项目
首先按照 TanStack Start 网站上的新建项目指南创建一个新的 TanStack Start 项目。
安装 Intlayer 包
使用您首选的包管理器安装必要的包:
bash复制代码复制代码到剪贴板
--interactive标志是可选的。如果您是 AI agent,请使用intlayer-cli init。此命令将检测您的环境并安装所需的包。例如:
bash复制代码复制代码到剪贴板
intlayer
solid-intlayer 将 Intlayer 与 Solid 应用程序集成的包。它为 Solid 国际化提供上下文提供者和 hooks。
vite-intlayer 包含用于将 Intlayer 与 Vite bundler 集成的 Vite 插件,以及用于检测用户首选语言环境、管理 cookies 和处理 URL 重定向的中间件。
配置您的项目
创建一个配置文件来配置应用程序的语言:
intlayer.config.ts复制代码复制代码到剪贴板
通过此配置文件,您可以设置本地化的 URL、中间件重定向、cookie 名称、内容声明的位置和扩展名、禁用控制台中的 Intlayer 日志等。关于可用参数的完整列表,请参考配置文档。
在您的 Vite 配置中集成 Intlayer
将 intlayer 插件添加到您的配置中:
vite.config.ts复制代码复制代码到剪贴板
intlayer()Vite 插件用于将 Intlayer 与 Vite 集成。它确保内容声明文件的构建并在开发模式下监控它们。它在 Vite 应用程序中定义 Intlayer 环境变量。此外,它提供别名以优化性能。创建根布局
通过使用
useParams检测当前语言环境并在html标签上设置lang和dir属性来配置您的根布局以支持国际化。src/routes/__root.tsx复制代码复制代码到剪贴板
创建语言环境布局
创建一个处理语言环境前缀并执行验证的布局。此布局将确保仅处理有效的语言环境。
如果您不需要在路由级别验证语言环境前缀,此步骤是可选的。
src/routes/{-$locale}/route.tsx复制代码复制代码到剪贴板
此处,
{-$locale}是一个动态路由参数,将被替换为当前的语言环境。这种符号使 slot 成为可选的,允许它与诸如'prefix-no-default'等路由模式一起使用。请注意,如果您在同一路由中使用多个动态段(例如
/{-$locale}/other-path/$anotherDynamicPath/...),此 slot 可能会导致问题。 对于'prefix-all'模式,您可能更倾向于将 slot 切换为$locale。 对于'no-prefix'或'search-params'模式,您可以完全删除 slot。声明您的内容
创建和管理您的内容声明以存储翻译:
src/contents/page.content.ts复制代码复制代码到剪贴板
您的内容声明可以在应用程序中的任何位置定义,只要它们包含在
contentDir目录中(默认为./app)。并匹配内容声明文件扩展名(默认为.content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml})。有关更多详情,请参考内容声明文档。
创建语言环境感知组件和 Hooks
为本地化导航创建一个
LocalizedLink组件:src/components/LocalizedLink.tsx复制代码复制代码到剪贴板
此组件有两个目标:
- 从 URL 中删除不必要的
{-$locale}前缀。 - 将语言环境参数注入到 URL 中,以确保用户直接重定向到本地化的路由。
然后我们可以创建一个
useLocalizedNavigatehook 用于编程导航:src/hooks/useLocalizedNavigate.tsx复制代码复制代码到剪贴板
- 从 URL 中删除不必要的
在您的页面中使用 Intlayer
在组件中请默认使用
useIntlayer:这是读取内容的推荐方式,编译器会把它解析为当前渲染的语言环境。仅在 Solid 树之外(路由head、loader 和服务端函数)才使用getIntlayer/getIntlayerAsync。在整个应用程序中访问您的内容字典:
本地化主页
src/routes/{-$locale}/index.tsx复制代码复制代码到剪贴板
在 Solid 中,
useIntlayer返回反应式内容(例如content)。您可以直接访问其属性。如果您想在
string属性中使用您的内容,例如alt、title、href、aria-label等,可以使用函数的值,如下所示:html复制代码复制代码到剪贴板
要了解更多关于
useIntlayerhook 的信息,请参考文档。创建语言切换器组件
创建一个组件以允许用户更改语言:
src/components/LocaleSwitcher.tsx复制代码复制代码到剪贴板
在 Solid 中,来自
useLocale的locale是一个信号访问器。使用locale()(带括号)以反应式方式读取其当前值。要了解更多关于
useLocalehook 的信息,请参考文档。HTML 属性管理
如步骤 5 所示,您可以在根组件中使用
useParams管理html标签的lang和dir属性。这确保在服务器和客户端上正确设置属性。src/routes/__root.tsx复制代码复制代码到剪贴板
添加中间件
您也可以使用
intlayerProxy为您的应用程序添加服务器端路由。该插件将自动根据 URL 检测当前语言环境并设置适当的语言环境 cookie。如果未指定语言环境,该插件将根据用户的浏览器语言首选项确定最合适的语言环境。如果未检测到语言环境,它将重定向到默认语言环境。注意,要在生产环境中使用
intlayerProxy,您需要将vite-intlayer包从devDependencies切换到dependencies。从 Intlayer v9 开始,
intlayerProxy()直接捆绑到intlayer()插件中,并通过routing.enableProxy选项(默认为true)默认启用。如下所示单独注册现在是可选的,为了向后兼容性以及需要控制插件顺序的设置而保留。设置routing.enableProxy: false以选择退出。参考 v9 发布说明。vite.config.ts复制代码复制代码到剪贴板
国际化您的元数据
getIntlayer会同步地在合并后的字典上解析,也就是包含所有已声明语言环境的那一份。head保持同步、无需等待,但整个多语言字典都会被打进发送到浏览器的路由分块中。src/routes/{-$locale}/index.tsx复制代码复制代码到剪贴板
适合较小的元数据字典、语言环境数量不多的项目,或原型开发阶段。
getIntlayerAsync(自 v9.4 起可用)的行为与getIntlayer相同,但构建插件会让它指向.intlayer/dynamic_dictionaries/中按语言环境拆分的分块,而不是合并字典。因此页面只会发送它所渲染的那一种语言环境。由于该分块是按需加载的,head变为async:src/routes/{-$locale}/index.tsx复制代码复制代码到剪贴板
如果一个
head要读取多个字典,请用Promise.all一并解析;逐行 await 每个getIntlayerAsync会把请求串成链式调用,而不是并行执行。代价是:动态 import 会在
head执行期间解析,处于文档渲染的关键路径上。在冷路由上这会让head延迟几毫秒,并可能略微拉低 LCP。改为在路由的
loader中解析字典,再于head中通过loaderData读回。已匹配路由的 loader 会并行运行,而staleTime: Infinity告诉 TanStack Router 该结果永不过期,于是按语言环境的分块只解析一次,之后由路由缓存提供,head得以保持同步。src/routes/{-$locale}/index.tsx复制代码复制代码到剪贴板
head可能在 loader 完成之前被调用,因此loaderData的类型可能为undefined。请保留可选链,或返回一个兜底标题。你保留了按语言环境拆分的分块,却无需在
head的关键路径上付出代价。代价在于开发体验:内容必须通过loaderData从 loader 显式传递到head。该选择哪种解析方式?
显示表格的所有内容在弹窗中打开表格以清晰地查看所有数据
静态解析 动态解析 带缓存的动态解析 API getIntlayergetIntlayerAsync(v9.4+)loader中的getIntlayerAsync(v9.4+)head签名同步 async同步,读取 loaderData发送的语言环境 所有已声明的语言环境 仅请求的语言环境 仅请求的语言环境 客户端导航 无需解析 每次匹配都重新执行 由路由缓存提供 开发体验 最简单 一个 await内容经由 loaderData传递在服务器操作中检索语言环境
您可能希望从服务器操作或 API 端点内部访问当前语言环境。 您可以使用
intlayer中的getLocalehelper。以下是使用 TanStack Start 的服务器函数的示例:
src/routes/{-$locale}/index.tsx复制代码复制代码到剪贴板
管理未找到页面
当用户访问不存在的页面时,您可以显示自定义的未找到页面,语言环境前缀可能会影响未找到页面的触发方式。
理解 TanStack Router 的 404 处理与区域设置前缀
在 TanStack Router 中,处理带有本地化路由的 404 页面需要多层次的方法:
- 专用 404 路由:用于显示 404 UI 的特定路由
- 路由级验证:验证区域设置前缀并将无效的前缀重定向到 404
- 全能路由:捕获区域设置段内所有不匹配的路径
src/routes/{-$locale}/404.tsx复制代码复制代码到剪贴板
src/routes/{-$locale}/route.tsx复制代码复制代码到剪贴板
src/routes/{-$locale}/$.tsx复制代码复制代码到剪贴板
提取你的组件内容
可选如果你有现有的代码库,转换数千个文件可能很耗时。
为了简化这个过程,Intlayer 提供了一个 compiler / extractor 来转换你的组件和提取内容。
要设置它,你可以在你的
intlayer.config.ts文件中添加一个compiler部分:intlayer.config.ts复制代码复制代码到剪贴板
import { type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { // ... 你的配置的其余部分 compiler: { /** * 指示编译器是否应该被启用。 */ enabled: true, /** * 定义输出文件路径 */ output: ({ fileName, extension }) => `./${fileName}${extension}`, /** * 指示转换后的组件是否应该被保存。 * * - 如果为 `true`,编译器将在磁盘中重写组件文件。所以转换将是永久的,编译器将在下一个过程中跳过转换。这样,编译器可以转换应用,然后可以被移除。 * * - 如果为 `false`,编译器将仅在构建输出中注入 `useIntlayer()` 函数调用,并保持基础代码库完整。转换将仅在内存中完成。 */ saveComponents: false, /** * 字典键前缀 */ dictionaryKeyPrefix: "", }, }; export default config;运行提取器来转换你的组件和提取内容
bash复制代码复制代码到剪贴板
从 v9 开始,
intlayerCompiler已包含在intlayer插件中。所以你不需要手动添加它。更新你的
vite.config.ts以包含intlayerCompiler插件:vite.config.ts复制代码复制代码到剪贴板
bash复制代码复制代码到剪贴板
预渲染和生成 Sitemap
Intlayer 配备了内置的 sitemap 生成器,可以帮助你轻松为应用创建 sitemap。它处理本地化路由并为搜索引擎添加必要的元数据。
Intlayer 生成的 sitemap 支持
xhtml:link命名空间(Hreflang XML 扩展)。与仅列出原始 URL 的默认 sitemap 生成器不同,Intlayer 会自动创建页面所有语言版本之间所需的双向链接(例如/about、/about?lang=fr和/about?lang=es)。这确保搜索引擎正确索引并为正确的受众提供正确的语言版本。要使用它,你首先需要配置你的
vite.config.ts以启用本地化路由的预渲染并禁用默认的 TanStack Start sitemap 生成。vite.config.ts复制代码复制代码到剪贴板
然后,创建一个使用
generateSitemap函数的src/routes/sitemap[.]xml.ts路由:src/routes/sitemap[.]xml.ts复制代码复制代码到剪贴板
配置 TypeScript
Intlayer 使用模块扩展来获得 TypeScript 的好处并使你的代码库更强大。
确保你的 TypeScript 配置包含自动生成的类型:
tsconfig.json复制代码复制代码到剪贴板
Git 配置
建议忽略 Intlayer 生成的文件。这可以避免将它们提交到您的 Git 仓库。
为此,您可以在 .gitignore 文件中添加以下指令:
复制代码到剪贴板
VS Code 扩展
为了提升 Intlayer 的开发体验,您可以安装官方的 Intlayer VS Code 扩展。
此扩展提供:
- 翻译键的自动补全。
- 缺失翻译的实时错误检测。
- 翻译内容的内联预览。
- 用于轻松创建和更新翻译的快速操作。
有关如何使用该扩展的更多详细信息,请参阅 Intlayer VS Code 扩展文档。
深入探索
如需深入了解,您可以实现可视化编辑器或使用 CMS 外置您的内容。
