新功能
通过 definePageMeta() 设置自定义路由
我们新增了使用 definePageMeta() API 为页面设置自定义路由的支持,这是目前推荐的页面自定义路由设置方式。
此方法适用于所有 customRoutes 模式,并且优先级高于通过 pages 选项或 defineI18nRoute() 宏设置的自定义路由。
自 v10.5 起,通过 definePageMeta() 设置的自定义路径适用于 所有 customRoutes 模式:
- 无需再切换到
customRoutes: 'meta',即可在页面组件中定义自定义路径。 - 迁移是增量进行的 — 可以一次将一个路由的自定义路径从
pages选项或宏迁移到页面组件中;definePageMeta()的值具有更高优先级,如果某个路由的路径来自多个来源,构建期间会记录警告。 - 路由元数据是构建时自定义路径的规范来源,因此项目和模块可以在
pages:extend钩子中为其添加或修改的路由设置自定义路径,请参阅钩子和模块。
要从 defineI18nRoute() 宏迁移,只需将其替换为 definePageMeta(),并使用相同的选项设置 i18n 属性:
<script setup>
definePageMeta({
i18n: {
paths: {
en: '/about-us',
fr: '/a-propos',
}
}
})
</script>
Nitro 端语言检测与重定向
语言检测和重定向已重新实现为由 Nitro 服务器处理,这使我们能够在请求生命周期的更早阶段进行重定向,从而提升性能。
之前的实现与预渲染结合使用时效果不佳,而新的实现解决了这个问题。
此更改使检测和重定向更加准确,更符合文档中描述的行为,但如果这在您的项目中引发问题,可以通过在模块选项中设置 experimental.nitroContextDetection: false 来禁用此功能。禁用该功能的选项为临时措施,未来版本将移除。
实验性严格 SEO 模式
我们新增了实验性选项 strictSeo,启用严格 SEO 模式,它改变了 i18n 头标签的处理方式。
启用严格 SEO 模式后,i18n 头标签将由模块内部管理,这带来了多个备受期待的改进:
- 设置本地化动态路由参数时,模块将不再为不支持的语言添加 alternate 标签。
- 使用
<SwitchLocalePathLink>的不支持语言链接将被禁用,其链接会被设置为'#',并带有用于样式的data-i18n-disabled属性。 - 在严格 SEO 模式下不再需要
useLocaleHead(),i18n 标签由模块自动设置,使用该函数将抛出错误。 - 规范化查询参数通过全局配置
experimental.strictSeo.canonicalQueryParams进行设置。 useSetI18nParams()会继承全局规范化查询参数配置,并可通过其选项参数覆盖。
如果此模式被证明稳定,它将在 v11 中成为默认模式,请尝试使用并报告你遇到的任何问题。
紧凑路由
我们新增了一个实验性选项 compactRoutes,用于改变带语言前缀的路由生成方式。它不会为每种语言分别创建独立路由,而是将符合条件的路由压缩为一个使用正则参数表示语言段的单一路由。
例如,在有三种语言(en、fr、ja)且使用 prefix 策略时,/about 页面通常会生成三条路由:
/en/about
/fr/about
/ja/about
启用 compactRoutes 后,这些路由会被压缩为一条:
/:locale(en|fr|ja)/about
可在 nuxt.config.ts 中启用:
export default defineNuxtConfig({
i18n: {
experimental: {
compactRoutes: true
}
}
})
这项改进的原因:
- 更少的路由 — 拥有大量页面和语言的应用会生成非常多的路由(页面数 × 语言数)。紧凑路由能显著减少这一数量,从而得到更小的路由表和更快的路由匹配。
- 更小的包体积 — 发送到客户端的路由配置更紧凑,从而减少 JavaScript 负载。
- 更好的可扩展性 — 路由数量与页面数量保持线性关系,而不是随着语言数量成倍增长。
它在不同策略下的工作方式:
prefix— 所有语言都会被压缩为一条路由。prefix_except_default— 默认语言保留其不带前缀的路由,而其他所有语言会被压缩为一条路由。prefix_and_default— 默认语言保留其不带前缀的路由,所有语言(包括默认语言)都会被压缩为一条路由。
何时路由无法被压缩:
并非所有路由都适合压缩。在以下情况下,路由仍会按语言分别生成:
- 它为不同语言定义了自定义路径(例如,英语为
/about,法语为/a-propos)。 - 它并非对所有已配置语言都可用(例如,某条路由在某些语言中被禁用)。
在这些情况下,模块会自动回退到该特定路由的标准按语言生成方式,同时仍会压缩所有符合条件的路由。
优化消息打包
我们更改了语言环境消息进入服务器构建的方式。以前,静态语言环境文件(JSON/JSON5/YAML)会交给打包器处理,打包器会将其展开为模块并为其生成源映射。由于服务器无论如何都会在运行时编译消息,这些工作只会拖慢构建速度。现在,这些文件会以内嵌原始消息的形式处理,并作为 Nitro 服务器资源提供给运行时。
此功能由 optimizeMessageBundling 控制,默认启用,也可以在 nuxt.config.ts 中关闭:
export default defineNuxtConfig({
i18n: {
experimental: {
optimizeMessageBundling: false
}
}
})
这项改进的原因:
- 更快的构建速度 — 在服务器构建中,打包器不再解析整个消息数据并为其生成源映射。根据我们的基准测试,对于语言环境文件较大的项目,构建时间减少了一半以上。
- 更低的内存使用量 — 构建峰值内存会随消息量增长;过去,语言环境文件非常大的项目可能会在服务器构建期间耗尽内存。
- 更小的服务器输出 — 消息数据不再展开为模块声明,从而减小服务器包的体积。
客户端包不受影响,消息仍会像之前一样在服务器上运行时编译,因此渲染消息的行为不会发生变化。
何时关闭此功能:
- 自定义 Nitro Rollup 插件会转换语言环境文件 — 由于这些文件不再被导入服务器模块图,该插件将无法再看到它们。
模块无法解析的语言环境文件会交由打包器处理,而不会导致构建失败,因此打包器能够接受的文件仍可正常工作 — 只是无法享受这项优化。
optimizeMessageBundling: false,并反馈相关情况。compilation.strictMessage。