This release is mostly about performance, and about making the domain features behave consistently.
Faster builds and faster SSR
Locale messages are no longer bundled into your server build as JavaScript, no longer shipped as client chunks when they are served from the messages endpoint, and no longer copied on every server-rendered request.
Building a Nuxt app with 10 locales of around 2,000 messages each and 10 pages:
| 10.5.0 | 10.6.0 | ||
|---|---|---|---|
| build time | 9.2s | 5.7s | 38% faster |
| peak build memory | 3.6 GB | 2.5 GB | 30% less |
| build output added by the module | 12.9 MB | 3.2 MB | 75% smaller |
| SSR throughput | 785 req/s | 1722 req/s | 2.2× higher |
Median of three runs on an M4 Pro with Nuxt 4.5; throughput over 10 concurrent connections. The same app without the module builds in 3.4s and outputs 3.2 MB.
How much of this you notice depends on how many messages your app loads: a few locales with a few hundred messages each will barely differ, larger message sets gain the most. It covers messages the module can read while building — .json, .yaml and .json5 files. Locale files written as .ts or .js produce their messages at runtime, so both their build and their SSR cost stay as they were. Apps that previously ran out of memory building large message sets should now complete.
This should work without any changes on your side. The new message handling can be turned off with experimental.optimizeMessageBundling: false if you run into trouble — and if you do, please let us know so we can sort it out.
Domains
differentDomains and multiDomainLocales now agree on which locale each domain serves, which URL a locale is advertised on, and where a visitor goes when the locale they asked for lives on another domain. hreflang and canonical links name one domain per locale, so every domain in your setup describes the same set of pages instead of each claiming the languages for itself.
10.5.0 could also stop serving a locale at its own domain root, redirecting / to the prefixed path and returning 404 for unprefixed paths. A domain that serves exactly one locale is treated as that locale's default again, so domainDefault is not needed for it.
Changelog
🚀 Features
- Add
experimental.optimizeMessageBundlingoption - by @BobbieGoede in #4068 (e7b6b) - domain: Restrict locales to a subset of
domains- by @BobbieGoede in #4085 (436c3)
🐞 Bug Fixes
- Strip protocol when matching domain to host - by @adamkasper, @cursoragent and @BobbieGoede in #4064 (86a4d)
- Let vue-router encode
switchLocalePathpaths - by @Vincentdevreede and @BobbieGoede in #4079 (03a8e) - Load locale files that use Nuxt app composables in the app - by @BobbieGoede in #4102 (917c0)
- Keep params encoded when resolving a localized route by path - by @BobbieGoede in #4104 (a4eee)
- bundler:
- Only precompile locale files the resource transform can re-emit - by @BobbieGoede in #4095 (930ff)
- domain:
- Resolve locale availability from host membership - by @BobbieGoede in #4083 (ef5d3)
- Resolve links for the host default locale under
prefix_and_default- by @BobbieGoede in #4087 (de62b) - Resolve domain config the same way at build time and runtime - by @BobbieGoede in #4090 (b38b7)
- Resolve the current origin from the host - by @BobbieGoede in #4103 (01d43)
- Redirect detection to the domain serving the detected locale - by @BobbieGoede in #4105 (03eba)
- Resolve a domain serving a single locale as its default - by @BobbieGoede in #4107 (efb9d)
- Serve every locale on a host matching no configured domain - by @BobbieGoede in #4108 (187b3)
- hmr:
- Use virtual module ids in
import.meta.hot.accept()for vite 8 - by @sawa-ko and @BobbieGoede in #4065 (329db)
- Use virtual module ids in
- routing:
- Resolve the unprefixed locale per domain - by @BobbieGoede in #4082 (7a2db)
- seo:
- Emit the same
x-defaulton every domain - by @BobbieGoede in #4089 (45d95) - Warn when a domain setup has no locale to annotate as
x-default- by @BobbieGoede in #4092 (e0706) - Resolve alternate and canonical links from one domain per locale - by @BobbieGoede in #4106 (21e1c)
- Emit the same
- types:
- Narrow locale head types to support
useHeadSafe- by @BobbieGoede in #4062 (59e5d) - Annotate the logger so its declaration stays portable - by @BobbieGoede in #4094 (93754)
- Prevent duplicate tsconfig paths for aliased deps - by @BuuBux and Kamil Kras in #4031 (d6930)
- Narrow locale head types to support
🏎 Performance
- Skip client locale chunks when using messages endpoint - by @BobbieGoede in #4067 (7d762)
- Keep locale messages out of server build graphs - by @BobbieGoede in #4070 (640e1)
- Avoid copying locale messages per ssr request - by @BobbieGoede in #4071 (46ab4)
- Enable
experimental.optimizeMessageBundlingby default - by @BobbieGoede in #4073 (ba6f3) - Keep message caching enabled for static locales in mixed projects - by @BobbieGoede in #4074 (d9d30)