fix(i18n): honor first-match-wins in computePreferredLocale codes branch#16600
Conversation
🦋 Changeset detectedLatest commit: 9dd036a The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Merging this PR will not alter performance
Comparing |
|
Assigning to @ematipico who understands the logic here the best. |
|
Hi, @ematipico , |
| 'astro': patch | ||
| --- | ||
|
|
||
| Fixes `computePreferredLocale` violating its "first match wins" semantics when the `i18n.locales` config contains object-form entries (`{ path, codes }`). The inner `break` only exited the codes-array loop, so a later normalize-equivalent code could overwrite the earlier match. The function now correctly returns the first matching code across both string and object entries. |
There was a problem hiding this comment.
Here's how you should write the changeset: https://contribute.docs.astro.build/docs-for-code-changes/changesets/#tips-and-examples
There was a problem hiding this comment.
I've just updated changeset.
ematipico
left a comment
There was a problem hiding this comment.
I don't the reason of this big refactor. The fix is way smaller. In the second loop, use break to exit from the outer loop.
|
Yes, you are right @ematipico , Thanks. |
|
Hi, @ematipico , |
| assert.equal(computePreferredLocale(req, locales), undefined); | ||
| }); | ||
|
|
||
| describe('regression: issue #16598 (first-match wins on object-form locales)', () => { |
There was a problem hiding this comment.
I don't understand why so much code. Just add three it like the rest of the cases.
There was a problem hiding this comment.
I just updated.
Please check again.
I appreciate your feedback.
|
Thanks, @ematipico . |
Changes
computePreferredLocaleviolating its "first match wins" semantics when aLocalesconfig contains object-form entries ({ path, codes }).breakin the codes-array branch only exits the inner loop, so a later normalize-equivalent code can overwrite an earlier (correct) match. The string-entry branch correctly breaks the outer loop.findFirstMatchingLocale(locales, target)helper that usesreturninstead ofbreak. Early return naturally exits both enclosing loops, making the bug type-impossible. Also normalizes the target once instead of per-iteration.Before:
[{ path: 'us', codes: ['EN-US'] }, 'en-us']+Accept-Language: en-us→'en-us'(wrong)[{ path: 'us', codes: ['EN'] }, { path: 'gb', codes: ['en'] }]+Accept-Language: en→'en'(wrong)After: Both return the first matching code:
'EN-US'and'EN'respectively.Testing