使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
版本历史
- 初始版本v7.0.02025/11/1
此页面的内容已使用 AI 翻译。
查看英文原文的最新版本如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
2025 年如何使用 next-intl 国际化你的 Next.js 应用
目录
什么是 next-intl?
next-intl 是一个专为 Next.js App Router 设计的流行国际化(i18n)库。它提供了一种无缝构建多语言 Next.js 应用的方法,具备出色的 TypeScript 支持和内置优化。
如果你愿意,也可以参考 next-i18next 指南,或者直接使用 Intlayer。
查看 next-i18next vs next-intl vs Intlayer 中的比较。
想了解这些库的由来,请阅读 JavaScript i18n 的发展史。
基准测试对 Next.js 上的 next-intl 有何结论
在实现翻译之前,了解 next-intl 的性能特征至关重要。i18n 基准测试 在不同配置和库下评估同一个包含 10 个页面、10 种语言的 Next.js 应用,以测量真实的 bundle 体积、字符串泄漏和 hydration 开销。
指标
动态 JSON 加载
在运行时懒加载翻译
有作用域的 JSON (命名空间)
每页翻译命名空间
这个指标是什么?
国际化库包的总 gzip 压缩大小。它仅包含 tree-shaking 和压缩(minification)后的提供者(provider)和内容检索逻辑。
为什么这很重要?
较小的库大小可减少初始 JavaScript 负载,从而缩短客户端的下载和执行时间。
视图形式
next-intl 在 Next.js 上的关键数据 (gzip):
在弹窗中打开表格以清晰地查看所有数据
| 配置 | 库体积 | 页面 JS 平均 | 其他语言泄漏 | 其他页面泄漏 |
|---|---|---|---|---|
| 基准 (无 i18n) | - | 141.0 KB | 0.0% | 0.0% |
next-intl | 14.7 KB | 153.6 KB | 4.2% | 89.8% |
@intlayer/next-intl (compat) | 8.0 KB | 148.7 KB | 0.0% | 0.0% |
next-intlayer (原生 Intlayer) | 5.5 KB | 141.3 KB | 0.0% | 0.0% |
要点:
- 避免全局消息目录: 在所有消息都在根 layout 中加载的标准配置下,发送到浏览器的翻译内容中约 89.8% 属于其他页面。在每个路由中使用
pick(messages, ['namespace'])可以消除这种泄漏,但需要手动维护。 - 运行时体积:
next-intl运行时为每个页面增加约 14.7 KB (gzip)。对于现有的next-intl应用,@intlayer/next-intl兼容适配器保留相同的 hooks (useTranslations、useFormatter等),同时将运行时体积降至约 8.0 KB,泄漏为 0%。原生next-intlayer可进一步降至 5.5 KB。
查看完整数据:Next.js 基准测试报告,以及 基准测试仓库。
Next.js 上的功能对比
在 Next.js App Router 项目通常需要的功能上,next-intl 与 next-i18next 和 Intlayer 的对比:
在弹窗中打开表格以清晰地查看所有数据
| 功能 | next-intlayer (Intlayer) | next-intl | next-i18next |
|---|---|---|---|
| 翻译靠近组件 | ✅ 内容与每个组件放在一起 | ❌ 集中式 JSON | ❌ 集中式 JSON |
| TypeScript 集成 | ✅ 自动生成的严格类型 | ✅ 良好,通过 AppConfig 扩展 | ⚠️ 基础 |
| 缺失翻译检测 | ✅ TypeScript 错误和构建时警告 | ⚠️ 运行时回退 | ⚠️ 运行时回退 |
| 富内容 (JSX、Markdown) | ✅ 直接支持 | ⚠️ 通过 t.rich 使用标签,不支持 Markdown | ⚠️ 通过 <Trans> 使用标签 |
| AI 翻译 | ✅ 使用你自己的提供商和 API key,带应用上下文 | ❌ 无 | ❌ 无 |
| 可视化编辑器 / CMS | ✅ 本地可视化编辑器 + 可选 CMS | ❌ 通过外部平台 | ❌ 通过外部平台 |
| 本地化路由 | ✅ 内置 (Next.js 和 Vite) | ✅ 内置 [locale] 段 | ✅ 内置 |
| 复数处理 | ✅ 基于枚举 | ✅ ICU | ✅ 基于后缀 (_one、_other) |
| 格式化 (日期、数字、货币) | ✅ 基于 Intl 的格式化器 | ✅ useFormatter | ✅ 基于 Intl |
| 内容格式 | ✅ .ts, .tsx, .js, .json, .md, .yaml | ✅ .json, .js, .ts | ⚠️ .json |
| ICU MessageFormat | ✅ 通过 format: "icu" | ✅ 原生 | ⚠️ 通过 i18next-icu |
| SEO 辅助 (hreflang、sitemap) | ✅ 元数据、sitemap 和 robots.txt 辅助函数 | ✅ 良好 | ✅ 良好 |
| Server Components | ✅ 在任意 Server Component 中直接访问 | ⚠️ 每个组件传递 t 或 await getTranslations() | ⚠️ 沿组件树向下传递 t |
| 按组件 tree-shaking | ✅ 构建时 (Babel / SWC) | ⚠️ 手动,每个路由使用 pick() | ⚠️ 手动,每个路由使用命名空间 |
| 懒加载 | ✅ 按语言和按字典 | ✅ 按语言,命名空间手动管理 | ✅ 按语言,命名空间手动管理 |
| 运行时体积 (gzip,基准测试) | 4.9 KB | 14.7 KB | 19.7 KB |
| CI 中的缺失翻译 | ✅ npx intlayer test | ⚠️ 未内置 | ⚠️ 未内置,运行时使用 saveMissing |
| 生态 / 社区 | ⚠️ 较小,增长迅速 | ✅ 大 | ✅ 非常大 |
运行时体积来自 Next.js 基准测试。详细讨论请阅读 next-i18next vs next-intl vs Intlayer。
你应该遵循的实践
在我们深入实现之前,以下是你应该遵循的一些实践:
- 设置 HTML 的
lang和dir属性
在你的布局中,使用getLocaleDirection(locale)计算dir,并设置<html lang={locale} dir={dir}>,以确保良好的无障碍访问和 SEO。 - 按命名空间拆分消息
按照 locale 和命名空间组织 JSON 文件(例如,common.json、about.json),只加载你需要的内容。 - 最小化客户端负载
在页面中,只向NextIntlClientProvider发送所需的命名空间(例如,pick(messages, ['common', 'about']))。 - 优先使用静态页面
尽可能使用静态页面,以获得更好的性能和 SEO。 - 服务器组件中的国际化(I18n)
服务器组件,比如页面或所有未标记为client的组件,都是静态的,可以在构建时预渲染。因此,我们需要将翻译函数作为 props 传递给它们。 - 设置 TypeScript 类型
为你的 locales 设置类型,以确保整个应用程序的类型安全。 - 代理重定向
使用代理来处理语言环境检测和路由,并将用户重定向到相应的带有语言前缀的 URL。 - 元数据、站点地图、robots.txt 的国际化
使用 Next.js 提供的generateMetadata函数对元数据、站点地图、robots.txt 进行国际化,以确保搜索引擎在所有语言环境中更好地发现你的内容。 - 本地化链接
使用Link组件本地化链接,将用户重定向到带有适当语言前缀的 URL。确保您的页面在所有语言环境中都能被发现非常重要。 - 自动化测试和翻译 自动化测试和翻译有助于节省维护多语言应用程序的时间。
查看我们的文档,了解有关国际化和 SEO 的所有内容:使用 next-intl 进行国际化 (i18n)。
在 Next.js 应用中逐步设置 next-intl 指南
查看 GitHub 上的应用模板。
以下是我们将创建的项目结构:
复制代码到剪贴板
安装依赖
使用 npm 安装必要的包:
bash复制代码复制代码到剪贴板
- next-intl:Next.js App Router 的核心国际化库,提供用于管理翻译的 hooks、服务器函数和客户端提供者。
配置项目
创建一个配置文件,定义你支持的语言环境并设置 next-intl 的请求配置。该文件作为你的国际化设置的唯一可信来源,并确保整个应用中的类型安全。
集中管理语言环境配置可以防止不一致问题,并且使未来添加或移除语言环境更加方便。
getRequestConfig函数会在每次请求时运行,仅加载每个页面所需的翻译,从而实现代码拆分并减少包大小。src/i18n.ts复制代码复制代码到剪贴板
定义动态语言路由
通过在您的应用程序文件夹中创建一个
[locale]目录来设置基于语言环境的动态路由。这允许 Next.js 处理基于语言环境的路由,其中每个语言环境成为 URL 的一部分(例如/en/about,/fr/about)。使用动态路由使 Next.js 能够在构建时为所有语言环境生成静态页面,从而提升性能和 SEO。布局组件根据语言环境设置 HTML 的
lang和dir属性,这对于无障碍访问和搜索引擎的理解至关重要。src/app/[locale]/layout.tsx复制代码复制代码到剪贴板
src/app/[locale]/about/page.tsx复制代码复制代码到剪贴板
创建您的翻译文件
为每个语言环境和命名空间创建 JSON 文件。此结构允许您逻辑性地组织翻译内容,并且只加载每个页面所需的内容。
按命名空间组织翻译(例如,
common.json、about.json)可以实现代码拆分并减少包大小。您只加载每个页面所需的翻译,从而提升性能。locales/en/common.json复制代码复制代码到剪贴板
locales/fr/common.json复制代码复制代码到剪贴板
locales/en/about.json复制代码复制代码到剪贴板
locales/fr/about.json复制代码复制代码到剪贴板
在页面中使用翻译
创建一个页面组件,在服务器端加载翻译,并将其传递给服务器和客户端组件。这确保了翻译在渲染之前加载,防止内容闪烁。
服务器端加载翻译可以提升SEO效果并防止FOUC(未翻译内容闪烁)。通过使用
pick仅将所需的命名空间发送给客户端提供者,我们可以最小化发送到浏览器的JavaScript包大小。src/app/[locale]/about/page.tsx复制代码复制代码到剪贴板
在客户端组件中使用翻译
客户端组件可以使用
useTranslations和useFormatter钩子来访问翻译和格式化函数。这些钩子从NextIntlClientProvider上下文中读取数据。客户端组件需要 React 钩子来访问翻译。
useTranslations和useFormatter钩子与 next-intl 无缝集成,并在语言环境更改时提供响应式更新。别忘了将所需的命名空间添加到页面的客户端消息中(只包含客户端组件实际需要的命名空间)。
src/components/ClientComponent.tsx复制代码复制代码到剪贴板
在服务器组件中使用翻译
服务器组件不能使用 React 钩子,因此它们通过父组件的 props 接收翻译和格式化函数。这种方法保持服务器组件的同步性,并允许它们嵌套在客户端组件内。
可能嵌套在客户端边界下的服务器组件需要是同步的。通过将翻译后的字符串和格式化的值作为 props 传递,我们避免了异步操作并确保正确渲染。在父页面组件中预先计算翻译和格式化。
src/components/ServerComponent.tsx复制代码复制代码到剪贴板
在你的页面或布局中,使用
next-intl/server中的getTranslations和getFormatter预先计算翻译和格式化,然后将它们作为 props 传递给服务器组件。更改内容语言
可选要使用 next-intl 更改内容语言,渲染指向相同路径名但切换语言环境的本地化链接。Provider 会自动重写 URL,因此你只需针对当前路由即可。
src/components/LocaleSwitcher.tsx复制代码复制代码到剪贴板
使用本地化的 Link 组件
可选next-intl提供了一个子包next-intl/navigation,其中包含一个自动应用当前活动语言环境的本地化链接组件。我们已经在@/i18n文件中为你提取好了它,所以你可以这样使用:src/components/MyComponent.tsx复制代码复制代码到剪贴板
在服务器操作中访问活动语言环境
可选服务器操作可以使用
next-intl/server读取当前语言环境。这对于发送本地化邮件或在提交的数据中存储语言偏好非常有用。src/app/actions/get-current-locale.ts复制代码复制代码到剪贴板
getLocale会读取由next-intl代理设置的 locale,因此它可以在服务器的任何地方使用:路由处理程序、服务器操作和边缘函数。国际化您的元数据
可选翻译内容很重要,但国际化的主要目标是让您的网站对全世界更具可见性。I18n 是通过适当的 SEO 显著提升您网站可见性的强大杠杆。
正确国际化的元数据帮助搜索引擎理解您的页面支持哪些语言。这包括设置 hreflang 元标签、翻译标题和描述,以及确保为每个语言环境正确设置规范 URL。
src/app/[locale]/about/layout.tsx复制代码复制代码到剪贴板
国际化您的网站地图
可选生成包含所有页面本地化版本的站点地图。这有助于搜索引擎发现并索引您内容的所有语言版本。
一个正确国际化的站点地图确保搜索引擎能够找到并索引您页面的所有语言版本,从而提升在国际搜索结果中的可见性。
src/app/sitemap.ts复制代码复制代码到剪贴板
国际化您的 robots.txt
可选创建一个 robots.txt 文件,正确处理所有受保护路由的所有语言版本。这确保搜索引擎不会索引任何语言的管理员或仪表盘页面。
为所有语言正确配置 robots.txt 可以防止搜索引擎在您的路由因语言不同而变化时索引敏感页面。
src/app/robots.ts复制代码复制代码到剪贴板
为本地化路由设置代理
可选创建一个代理,自动检测用户的首选语言环境,并将其重定向到相应的带有语言前缀的 URL。next-intl 提供了一个方便的代理函数,可以自动处理此操作。
代理确保用户访问您的网站时会自动重定向到他们偏好的语言。它还会保存用户的偏好,以便未来访问时使用,从而提升用户体验。
src/proxy.ts复制代码复制代码到剪贴板
为语言环境设置 TypeScript 类型
可选设置 TypeScript 将帮助您获得键的自动补全和类型安全。
为此,您可以在项目根目录下创建一个 global.ts 文件,并添加以下代码:
global.ts复制代码复制代码到剪贴板
此代码将使用模块增强(Module Augmentation)将 locales 和 messages 添加到 next-intl 的 AppConfig 类型中。
使用 Intlayer 自动化您的翻译工作
可选Intlayer 是一个 免费 和 开源 的库,旨在协助您的应用程序的本地化过程。虽然 next-intl 负责翻译的加载和管理,Intlayer 则帮助自动化翻译工作流程。
手动管理翻译既耗时又容易出错。Intlayer 自动化翻译的测试、生成和管理,节省您的时间,并确保整个应用程序的一致性。
Intlayer 允许您:
在代码库中任意位置声明您的内容
Intlayer 允许您使用.content.{ts|js|json}文件在代码库中任意位置声明内容。这将有助于更好地组织内容,确保代码库的可读性和可维护性。测试缺失的翻译 Intlayer 提供可集成到您的 CI/CD 流水线或单元测试中的测试功能。了解更多关于测试您的翻译。
自动化您的翻译
Intlayer 提供了一个 CLI 和一个 VSCode 扩展来自动化您的翻译。它可以集成到您的 CI/CD 流水线中。了解更多关于自动化您的翻译。
您可以使用您自己的 API 密钥和您选择的 AI 提供商。它还提供上下文感知的翻译,详见填充内容。连接外部内容
Intlayer 允许您将内容连接到外部内容管理系统(CMS)。以优化的方式获取内容并将其插入到您的 JSON 资源中。了解更多关于获取外部内容的信息。可视化编辑器
Intlayer 提供免费的可视化编辑器,使用可视化编辑器编辑您的内容。了解更多关于可视化编辑您的翻译的信息。
以及更多功能。要发现 Intlayer 提供的所有功能,请参阅Intlayer 的优势文档。
有关详细的性能基准测试和对比,请参阅:
评论
暂无评论。成为第一个分享您想法的人吧。
