使用 next-intl 国际化 Next.js 应用
语言路由、服务端渲染翻译、RTL 布局与 hreflang SEO,避免客户端闪烁。
国际化是服务全球受众应用的基础要求。在 Next.js App Router 时代,next-intl 等库已成为管理翻译、语言路由和多语言 SEO 的事实标准。本指南介绍构建性能良好、搜索引擎排名靠前并尊重文化惯例(包括从右到左布局)的多语言 React 应用的成熟模式。
为 Next.js 选择 i18n 策略
App Router 改变了 Next.js 处理国际化的方式。Pages Router 的内置 i18n 配置不再适用,团队必须选择与新模式集成的库。next-intl 是最广泛采用的选项,因为它开箱即用地提供类型安全的消息格式化、语言感知导航和基于中间件的语言检测。
评估方案时,请预先考虑以下架构决策:
- URL 结构 — 基于前缀(
/en/about、/de/about)与基于域名(en.example.com、de.example.com)。 - 默认语言处理 — 默认语言是否出现在 URL 中或从请求头推断。
- 翻译存储 — JSON 文件、CMS 集成或翻译管理平台。
- 回退行为 — 次要语言缺少翻译键时的处理方式。
基于前缀的路由是大多数应用的推荐默认方案。它保持部署简单、适用于静态托管,并为搜索引擎提供关于语言变体的清晰信号。
设置语言路由
next-intl 使用 Next.js 中间件检测用户首选语言并将请求重写到相应的语言段。中间件在边缘运行,增加可忽略延迟,同时确保每页以正确语言提供内容。
// middleware.ts
import createMiddleware from "next-intl/middleware";
import { routing } from "./i18n/routing";
export default createMiddleware(routing);
export const config = {
matcher: ["/", "/(de|en|fr|ar)/:path*"],
};
// i18n/routing.ts
import { defineRouting } from "next-intl/routing";
export const routing = defineRouting({
locales: ["en", "de", "fr", "ar"],
defaultLocale: "en",
localePrefix: "always",
});
你的 app 目录结构镜像语言配置。每种语言在 app/[locale]/ 下有自己的段,共享布局用一致的导航和页脚内容包裹翻译页面。
语言感知导航
切勿在链接中硬编码路径。使用 next-intl 提供的导航辅助函数自动生成带语言前缀的 URL。这可在添加或删除语言时防止链接损坏,并确保活动语言上下文在客户端导航中传播。
import { Link } from "@/i18n/navigation";
export function NavBar() {
return (
<nav>
<Link href="/about">About</Link>
<Link href="/pricing">Pricing</Link>
</nav>
);
}
组织翻译消息
构建消息文件结构以随应用扩展。扁平 JSON 适合小项目,但嵌套命名空间可防止合并冲突,并在翻译数量增长到数千时提高可发现性。
- 按功能或页面分组消息 —
home.json、checkout.json、errors.json。 - 使用描述性键名 —
checkout.payment.submitButton而非btn1。 - 保持 ICU 消息格式语法一致,用于复数和插值。
- 部署前与母语者建立审查工作流。
仅加载页面需要的命名空间,避免发送未使用的翻译。next-intl 支持懒加载消息模块,即使有数十种语言也能保持初始包体积可控。
从右到左(RTL)布局支持
支持阿拉伯语和希伯来语等 RTL 语言不仅需要翻译字符串。布局方向、文本对齐、图标镜像和动画方向都需在切换到 RTL 语言时适配。
根据活动语言在根 HTML 元素上设置 dir 属性:
// app/[locale]/layout.tsx
import { getLocale, getMessages } from "next-intl/server";
const rtlLocales = ["ar", "he", "fa"];
export default async function LocaleLayout({ children, params }) {
const locale = await getLocale();
const direction = rtlLocales.includes(locale) ? "rtl" : "ltr";
return (
<html lang={locale} dir={direction}>
<body>{children}</body>
</html>
);
}
在整个样式表中使用 CSS 逻辑属性。将 margin-left 替换为 margin-inline-start,padding-right 替换为 padding-inline-end,text-align: left 替换为 text-align: start。Tailwind CSS v4 包含逻辑属性工具类(ms-4、pe-2)可自动处理。
多语言网站 SEO
搜索引擎需要明确信号来理解页面之间的语言关系。没有正确的 hreflang 标签和规范 URL,你可能面临重复内容惩罚和错误的语言索引。
实施以下 SEO 要点:
- hreflang 链接标签 — 在文档 head 中声明每页的所有语言变体。
- 规范 URL — 每个语言页面应规范到自身,而非默认语言。
- 翻译元数据 — 标题、描述和 Open Graph 标签必须本地化,而非从默认语言复制。
- XML 站点地图 — 生成按语言分的站点地图或带 hreflang 注解的统一站点地图。
- 结构化数据 — 本地化 JSON-LD 模式标记以获得富搜索结果。
next-intl 与 Next.js 元数据 API 集成,允许你在每页的 generateMetadata 函数中定义语言特定标题和描述。结合遍历语言和路由的站点地图生成器,实现全面的搜索引擎覆盖。
测试与质量保证
国际化缺陷很隐蔽,因为它们常仅在特定语言组合中出现。缺少的翻译键可能在生产中渲染为原始键字符串。RTL 布局缺陷可能仅在阿拉伯语中破坏导航。在 CI 流水线中构建自动化检查以尽早发现问题。
- 验证所有语言包含相同的翻译键集。
- 对 RTL 语言运行视觉回归测试以捕获布局破坏。
- 用各种 Accept-Language 头组合测试语言检测。
- 验证日期、数字和货币格式符合语言惯例。
- 检查页面权重 — 确保加载所有语言消息不会膨胀包体积。
国际化是持续承诺,而非一次性设置任务。随着应用增长,新功能引入新字符串,在各语言间保持翻译一致性需要纪律和工具。从一开始就采用 next-intl、结构化语言路由、RTL 支持和 SEO 最佳实践,你将打下随着受众跨语言和地区扩展而优雅扩展的基础。