fix: walk vue-i18n's actual fallback chain instead of approximating it - #4128
fix: walk vue-i18n's actual fallback chain instead of approximating it#4128Vincentdevreede wants to merge 4 commits into
Conversation
✅ Action performedReview finished.
|
WalkthroughThe locale fallback resolver now builds ordered fallback chains from locale hierarchy, explicit fallback maps, default targets, and suppression markers. It prevents cycles, preserves explicit fallback tags, filters implicit tags against configured locales, and removes duplicate or primary locales. A new test suite covers the resolution rules. Documentation explains base-locale fallback, redirect behavior, and Estimated code review effort: 4 (Complex) | ~45 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/content/docs/02.guide/11.locale-fallback.md`:
- Around line 29-33: Update the paragraph under “Implicit fallback for region
tags” to state that `en-US` normally tries `en` before `fallbackLocale`, except
when an exact `fallbackLocale` entry for `en-US` is configured, which takes
precedence and prevents the base-language walk.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 3d68acf9-93c5-4e43-bb59-d45d0a7a7d5f
📒 Files selected for processing (3)
docs/content/docs/02.guide/11.locale-fallback.mdsrc/runtime/shared/locales.tstest/locales.test.ts
| ## Implicit fallback for region tags | ||
|
|
||
| Vue I18n also falls back a region tagged locale to its base language tag on its own, before it even looks at `fallbackLocale`. A missing key on `en-US` tries `en` first, regardless of what `fallbackLocale` says. Nuxt i18n lazy loads that base tag's messages too, so this keeps working, as long as the base tag is also a configured locale. If it isn't configured, there's no file to load for it and nothing changes. | ||
|
|
||
| To stop a locale from trying its own base tag, add a `fallbackLocale` entry keyed on that exact locale. Once such an entry exists, it takes over before the base tag walk ever starts: |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the exact-entry exception.
Line 31 says that en-US tries en regardless of fallbackLocale. An exact fallbackLocale['en-US'] entry prevents that walk, as Line 33 states. State this exception in Line 31.
Proposed fix
-Vue I18n also falls back a region tagged locale to its base language tag on its own, before it even looks at `fallbackLocale`. A missing key on `en-US` tries `en` first, regardless of what `fallbackLocale` says.
+Vue I18n also falls back from a region-tagged locale to its base language tag before it uses `default` or entries for other locales. If `fallbackLocale` has no exact `en-US` entry, a missing key on `en-US` tries `en` first.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## Implicit fallback for region tags | |
| Vue I18n also falls back a region tagged locale to its base language tag on its own, before it even looks at `fallbackLocale`. A missing key on `en-US` tries `en` first, regardless of what `fallbackLocale` says. Nuxt i18n lazy loads that base tag's messages too, so this keeps working, as long as the base tag is also a configured locale. If it isn't configured, there's no file to load for it and nothing changes. | |
| To stop a locale from trying its own base tag, add a `fallbackLocale` entry keyed on that exact locale. Once such an entry exists, it takes over before the base tag walk ever starts: | |
| ## Implicit fallback for region tags | |
| Vue I18n also falls back from a region-tagged locale to its base language tag before it uses `default` or entries for other locales. If `fallbackLocale` has no exact `en-US` entry, a missing key on `en-US` tries `en` first, regardless of what `fallbackLocale` says. Nuxt i18n lazy loads that base tag's messages too, so this keeps working, as long as the base tag is also a configured locale. If it isn't configured, there's no file to load for it and nothing changes. | |
| To stop a locale from trying its own base tag, add a `fallbackLocale` entry keyed on that exact locale. Once such an entry exists, it takes over before the base tag walk ever starts: |
🧰 Tools
🪛 LanguageTool
[grammar] ~31-~31: Use a hyphen to join words.
Context: ... tags Vue I18n also falls back a region tagged locale to its base language tag o...
(QB_NEW_EN_HYPHEN)
[style] ~31-~31: To elevate your writing, try using more formal phrasing here.
Context: ...s that base tag's messages too, so this keeps working, as long as the base tag is also a conf...
(CONTINUE_TO_VB)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/content/docs/02.guide/11.locale-fallback.md` around lines 29 - 33,
Update the paragraph under “Implicit fallback for region tags” to state that
`en-US` normally tries `en` before `fallbackLocale`, except when an exact
`fallbackLocale` entry for `en-US` is configured, which takes precedence and
prevents the base-language walk.
Summary
Builds on the changes from #4124.
That PR fixed one specific case: a region tagged locale like
en-USimplicitly falls back to its base tagenbefore vue-i18n even looks atfallbackLocale, and lazy loading never fetched that base tag's messages unless it was also listed explicitly.Testing that fix directly against vue-i18n's real internal resolver(
fallbackWithLocaleChainin@intlify/core-base) showed it only covered part of the actual behavior. vue-i18n'sreal algorithm is a per-tag walk, not base tags unioned with whatever's infallbackLocale:fallbackLocalemap entry keyed by the exact tag being resolved intercepts the walk before it ever reaches that tag's own base tag.!on any entry stops the walk at that tag, skipping its own base tag descent, scoped to just that one redirect.defaultblock still applies afterward regardless of whether the walk was redirected.The previous approach could both under fetch (miss locales vue-i18n would actually reach) and over fetch (pull in locales vue-i18n would never touch).
This replaces that approximation with a small walk (
walkLocale,walkBlock,walkFallbackChaininsrc/runtime/shared/locales.ts) that mirrors vue-i18n's real chain building closely enough to answer which locales it will actually reach, without taking a runtime dependency on that internal.Also documents the implicit fallback behavior and how to control it in
docs/content/docs/02.guide/11.locale-fallback.md, including the!suffix and its scoping (it stops the redirect target's own walk, not the whole locale's fallback everywhere).Summary by CodeRabbit
New Features
Documentation