国际化路由 (i18n)
示例
自 v10.0.0
版本起,Next.js 已内置支持国际化 (i18n) 路由功能。您只需提供语言环境列表、默认语言环境以及特定域名的语言配置,Next.js 将自动处理路由转换。
当前的国际化路由支持旨在通过简化路由和语言环境解析,与现有的国际化解决方案如 react-intl
、react-i18next
、lingui
、rosetta
、next-intl
、next-translate
、next-multilingual
、tolgee
等形成互补。
快速开始
首先,在 next.config.js
文件中添加 i18n
配置。
语言环境采用 UTS 语言标识符标准格式定义。
通常语言标识符由语言代码、地区代码和文字系统组成,用连字符分隔:语言-地区-文字系统
。其中地区和文字系统为可选项。例如:
en-US
- 美国英语nl-NL
- 荷兰荷兰语nl
- 荷兰语(无特定地区)
如果用户语言环境是未配置的 nl-BE
,系统将优先重定向到 nl
(若存在),否则回退到默认语言环境。因此建议包含国家级的语言环境作为备用方案。
语言环境策略
提供两种语言环境处理策略:子路径路由和域名路由。
子路径路由
子路径路由将语言代码置于 URL 路径中。
以上配置中,en-US
、fr
和 nl-NL
将成为可路由的语言环境,其中 en-US
为默认语言环境。对于 pages/blog.js
页面,以下 URL 将可用:
/blog
/fr/blog
/nl-nl/blog
默认语言环境不包含前缀。
域名路由
通过域名路由,您可以将不同语言环境配置到不同域名:
例如对于 pages/blog.js
页面,以下 URL 将可用:
example.com/blog
www.example.com/blog
example.fr/blog
example.nl/blog
example.nl/nl-BE/blog
自动语言环境检测
当用户访问应用根路径(通常为 /
)时,Next.js 会基于 Accept-Language
请求头和当前域名自动检测用户偏好语言。
如果检测到非默认语言环境,用户将被重定向至:
- 使用子路径路由时:带语言前缀的路径
- 使用域名路由时:配置了该语言环境为默认值的域名
使用域名路由时,若带有 Accept-Language: fr;q=0.9
请求头的用户访问 example.com
,将被重定向至 example.fr
,因为该域名默认处理 fr
语言环境。
使用子路径路由时,用户将被重定向至 /fr
。
为默认语言环境添加前缀
在 Next.js 12 及更高版本中,通过 中间件 可以实现为默认语言环境添加前缀的 解决方案。
例如,以下 next.config.js
文件支持多种语言,注意其中特意添加了 "default"
语言环境:
然后通过 中间件 添加自定义路由规则:
该 中间件 会跳过为 API 路由 和 静态资源(如字体或图片)添加默认前缀。当请求默认语言环境时,我们将重定向至带 /en
前缀的路径。
禁用自动语言检测
可通过以下配置禁用自动语言检测:
当 localeDetection
设为 false
时,Next.js 将不再基于用户偏好语言自动重定向,仅提供从域名或路径中检测到的语言环境信息。
访问语言环境信息
您可以通过 Next.js 路由访问语言环境信息。例如使用 useRouter()
钩子时,以下属性可用:
locale
- 当前激活的语言环境locales
- 所有配置的语言环境defaultLocale
- 配置的默认语言环境
使用 getStaticProps
或 getServerSideProps
预渲染 页面时,语言环境信息会通过 上下文参数 提供给函数。
使用 getStaticPaths
时,配置的语言环境会通过上下文参数的 locales
属性提供,默认语言环境通过 defaultLocale
提供。
语言环境切换
您可以使用 next/link
或 next/router
实现语言环境切换。
对于 next/link
,可通过 locale
属性指定切换至不同于当前激活语言的环境。若不提供 locale
属性,客户端切换时将使用当前激活的语言环境。例如:
直接使用 next/router
方法时,可通过切换选项指定目标语言环境。例如:
如需仅切换语言环境而保留所有路由信息(如 动态路由 查询参数或隐藏的 href 查询值),可将 href
参数设为对象:
关于 router.push
对象结构的更多信息,请参阅 此处。
如果 href 已包含语言环境前缀,可以禁用自动处理语言前缀:
使用 NEXT_LOCALE
Cookie
Next.js 支持通过 NEXT_LOCALE=语言代码
Cookie 覆盖 accept-language 请求头。可通过语言切换器设置此 Cookie,当用户再次访问站点时,从 /
重定向时将优先采用 Cookie 中指定的语言环境。
例如,若用户请求头偏好 fr
语言环境,但设置了 NEXT_LOCALE=en
Cookie,则访问 /
时将重定向至 en
语言环境路径,直到 Cookie 被删除或过期。
搜索引擎优化
Next.js 会自动为 <html>
标签添加 lang
属性。
由于 Next.js 无法识别页面的语言变体,您需要使用 next/head
手动添加 hreflang
元标签。关于 hreflang
的更多信息,请参阅 Google 站长文档。
静态生成相关说明
注意:国际化路由不与
output: 'export'
导出模式兼容,因其不依赖 Next.js 路由层。不使用output: 'export'
的混合式 Next.js 应用可获得完整支持。
动态路由与 getStaticProps
页面
对于使用 getStaticProps
的 动态路由 页面,所有需要预渲染的语言变体都需通过 getStaticPaths
返回。除了返回 params
对象外,还可指定 locale
字段以声明要渲染的语言环境。例如:
对于 自动静态优化 和非动态的 getStaticProps
页面,会为每个语言环境生成一个版本。这需要特别注意,因为根据配置的语言环境数量,可能会显著增加构建时间。
例如,若配置了 50 个语言环境和 10 个使用 getStaticProps
的非动态页面,则 getStaticProps
将被调用 500 次。每次构建会生成这 10 个页面的 50 个语言版本。
要减少动态页面的构建时间,可使用 fallback
模式。这样只需在 getStaticPaths
中返回最受欢迎的路径和语言组合用于预渲染,剩余页面将在运行时按需生成。
自动静态优化页面
对于 自动静态优化 的页面,会为每个语言环境生成一个版本。
非动态 getStaticProps 页面
对于非动态的 getStaticProps
页面,同样会为每个语言环境生成版本。getStaticProps
会针对每个渲染的语言环境被调用。如需排除某些语言环境的预渲染,可从 getStaticProps
返回 notFound: true
,该语言变体将不会被生成。
i18n 配置限制
locales
:最多支持 100 个语言环境domains
:最多支持 100 个域名配置项
须知:这些限制最初是为了避免 构建时的性能问题。在 Next.js 12 中,您可以通过 中间件 实现自定义路由来突破这些限制。