使用 next-intl 在 Next.js 应用中开启国际化
目前 Next.js 推荐的路由方式是 App Router,所以本文不再介绍 Pages Router,感兴趣的请阅读官方文档 next-intl Pages Router。
next-intl 为 App Router 提供了两种配置选项:
- 带有路由:使用路由片段 locale 或者域名,例如
/en/about
和en.example.com/about
。 - 不带路由:基于用户设置。
由于第一种方式在后续的路由跳转必须携带 locale 参数,比较不方便,因此本文选择介绍第二种不带路由的方式。
一、准备工作
使用 pnpm 创建项目
pnpm create next-app

项目选项
运行项目,本文在此页面上进行配置

初始页面
二、安装和配置
1. 安装 next-intl
pnpm add next-intl
2. 在根目录创建 messages
文件夹,并在此文件夹下创建 zh.json
和 en.json
Home
为命名空间,后面需要用到,可以在 json 中声明多个,表示不同场景。
- en.json
- zh.json
3. 配置 next.config.mjs
4. 创建 i18n/config.js
,保存配置
5. 创建 i18n/service.js
,获取、设置区域
next-intl 在 cookie 中设置了 NEXT_LOCALE
字段,用来保存区域配置。
获取区域配置优先级如下:
- 从 cookies 中读取
NEXT_LOCALE
,有值则直接返回 - 从 headers 中读取解析
accept-language
,并判断是否在系统支持的语言中
6. 创建 i18n/request.js
,返回国际化配置
7. 修改 app/layout.js
使用 getLocale
和 getMessages
可以获取 i18n/request.js
返回的语言配置,将 locale 设置到 html 的 lang 属性,将 messages 传递给 NextIntlClientProvider
。
三、使用
同步服务端组件与客户端组件
文本数量较少的情况下,建议将文本通过 props 传递给客户端组件。在客户端组件中调用
useTranslations
会将 next-intl 代码打包进客户端 js 中,导致 bundle 体积增大,影响加载性能。
- 调用
useTranslations
,传入命名空间js const t = useTranslations('Home')
- 在 jsx 中调用
js <p>{t('docs')}</p>
异步服务端组件
关于其他更多用法,例如插值语法、富文本、HTML 标记、数组、数字格式、日期时间格式等,请参考文档 https://next-intl.dev/docs/usage/messages。
四、语言切换
创建 components/LocaleSwitcher.js
组件,并在 app/page.js
中引入
由于我们之前在 Server Action setUserLocale
中通过 cookies 设置了语言区域,Next.js 会将新的 cookie 和 DOM 返回给客户端。

RSC Payload
效果如下:

切换语言效果图