Skip to content

Conversation

@darcyYe
Copy link
Contributor

@darcyYe darcyYe commented Nov 12, 2025

Summary

Fixed issues with i18n language tag fallback logic (resolves LOG-12467). Key improvements include:

  • Refactored language matching algorithm: Uses Intl.getCanonicalLocales() to normalize language tags, enabling more accurate language matching
  • Improved fallback logic: When requesting base languages (e.g., pl), it now correctly falls back to built-in regional variants (e.g., pl-PL)
  • Enhanced custom language support: Better handling of custom language tag matching with built-in languages
  • Unified language processing: Added findSupportedLanguageTag and matchSupportedLanguageTag functions in @logto/language-kit to centralize language matching logic

Testing

  • Added unit tests to validate language fallback logic
  • Tested base language to regional variant fallback (e.g., pl → pl-PL)
  • Verified custom language matching priorities
  • Tested default fallback behavior when no matches found
  • Ensured existing functionality remains unaffected

Checklist

  • .changeset
  • unit tests
  • integration tests
  • necessary TSDoc comments

@darcyYe darcyYe requested review from a team and Copilot November 12, 2025 07:15
@github-actions
Copy link

github-actions bot commented Nov 12, 2025

COMPARE TO master

Total Size Diff 📈 +8.79 KB

Diff by File
Name Diff
packages/core/src/middleware/koa-email-i18n.test.ts 0 Bytes
packages/core/src/routes/well-known/well-known.phrases.test.ts 📈 +3 Bytes
packages/core/src/utils/i18n.test.ts 📈 +1.82 KB
packages/core/src/utils/i18n.ts 📈 +325 Bytes
packages/phrases-experience/src/index.ts 📈 +60 Bytes
packages/phrases/src/index.ts 📈 +52 Bytes
packages/toolkit/language-kit/package.json 📈 +40 Bytes
packages/toolkit/language-kit/src/utility.test.ts 📈 +2.24 KB
packages/toolkit/language-kit/src/utility.ts 📈 +4.19 KB
pnpm-lock.yaml 📈 +81 Bytes

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the i18n language tag fallback logic to improve language matching and fallback behavior. The key improvement is the addition of canonical locale normalization using Intl.getCanonicalLocales(), which enables better matching between language variants (e.g., pl can now correctly fallback to pl-PL).

Key Changes:

  • Added findSupportedLanguageTag and matchSupportedLanguageTag functions in @logto/language-kit to centralize language matching logic with improved fallback support
  • Refactored getDefaultLanguageTag functions in both phrases packages to use the new matching logic instead of the previous fallback utility
  • Updated getExperienceLanguage in core to prioritize custom languages before falling back to built-in languages

Reviewed Changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds @silverhand/essentials dependency for language-kit package
packages/toolkit/language-kit/package.json Adds @silverhand/essentials as a dev dependency
packages/toolkit/language-kit/src/utility.ts Implements new language matching functions with canonical locale normalization
packages/toolkit/language-kit/src/utility.test.ts Adds test coverage for new language matching functions
packages/phrases/src/index.ts Refactors getDefaultLanguageTag to use new findSupportedLanguageTag function
packages/phrases-experience/src/index.ts Refactors getDefaultLanguageTag to use new findSupportedLanguageTag function
packages/core/src/utils/i18n.ts Updates getExperienceLanguage to use new language matching functions with separate custom/built-in language handling
packages/core/src/utils/i18n.test.ts Adds test coverage for updated getExperienceLanguage function
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return;
}

const base = canonical.split('-')[0] ?? canonical;
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expression canonical.split('-')[0] ?? canonical is redundant. split()[0] will always return a string (at minimum, the original string if no delimiter is found), so it will never be nullish. The nullish coalescing operator ?? has no effect here. Consider simplifying to canonical.split('-')[0].

Suggested change
const base = canonical.split('-')[0] ?? canonical;
const base = canonical.split('-')[0];

Copilot uses AI. Check for mistakes.
return directMatch;
}

const base = canonicalPreferred.split('-')[0] ?? canonicalPreferred;
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expression canonicalPreferred.split('-')[0] ?? canonicalPreferred is redundant. split()[0] will always return a string (at minimum, the original string if no delimiter is found), so it will never be nullish. The nullish coalescing operator ?? has no effect here. Consider simplifying to canonicalPreferred.split('-')[0].

Suggested change
const base = canonicalPreferred.split('-')[0] ?? canonicalPreferred;
const base = canonicalPreferred.split('-')[0];

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +82
if (!base) {
continue;
}

Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition if (!base) is unreachable. Since base is assigned from split('-')[0], it will always be a non-empty string (at minimum, the value of canonicalPreferred itself). This check can be removed.

Suggested change
if (!base) {
continue;
}

Copilot uses AI. Check for mistakes.
@github-actions github-actions bot added size/l and removed size/l labels Nov 12, 2025
@darcyYe darcyYe force-pushed the yemq-fix-i18n-language-tag-fallback-logic branch from ead5cb5 to 678f5bb Compare November 12, 2025 10:08
@github-actions github-actions bot added size/l and removed size/l labels Nov 12, 2025
@darcyYe darcyYe marked this pull request as ready for review November 12, 2025 11:29
@github-actions github-actions bot added size/l and removed size/l labels Nov 12, 2025
Copy link
Member

@charIeszhao charIeszhao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. But please take a look at the copilot comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants