Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix display language not switching correctly to Chinese on native. #6621

Merged
merged 2 commits into from
Nov 22, 2024

Conversation

auroursa
Copy link
Contributor

@auroursa auroursa commented Nov 22, 2024

Why

In web development, language codes generally follow the RFC 1766 standard. In this standard, the language tag for Chinese is typically written as: zh-CN, zh-TW, zh-HK.

However, in Android and iOS, language codes follow the RFC 4646 standard, which further distinguishes Simplified Chinese (Hans) and Traditional Chinese (Hant). The language tags in this standard look like: zh-Hans-CN, zh-Hant-TW, zh-Hant-HK

When using getLocales().languageTag from expo-localization on an Android device (with system language set to Simplified Chinese), it will return this output:

[{"languageTag": "zh-Hans-CN"}]

This cannot be matched to existing AppLanguage, so it will rollback to English. Because AppLanguage naming follows RFC 1766, which is still widely used in browsers. Therefore, we cannot rename Chinese AppLanguage to following RFC 4646.

This patch is meant to solve this issue by converting the RFC 4646 output from the device into RFC 1766, just like how we handle incorrect languageCode on legacy Java devices (#4461).

With this patch, now using getLocales().languageTag will return the following output:

[{"languageTag": "zh-CN"}]

Based on #5384, the app can now correctly handle language tags with region codes. This allows it to match the existing zh-CN in AppLanguage and display Chinese when the app is opened for the first time, instead of rolling back to English.

It's hard to say RFC 1766 or RFC 4646 which standard is better, but both will likely coexist for a long time. Web development is unlikely to transition to RFC 4646, as it would break browser behavior, and W3C seem to prefer RFC 1766.

Always bear in mind that the golden rule is to keep your language tag as short as possible. Only add further subtags to your language tag if they are needed to distinguish the language from something else in the context where your content is used.

For now, Chinese is one of the few languages that requires mapping conversion. Most languages work as expected under either standard. So this patch only includes conversion mapping for Chinese. I prefer not to rewrite the logic in the later parts of the code.

Before:

before.mp4

After:

after.mp4

@auroursa
Copy link
Contributor Author

Okay... There are so many variations of Chinese in the Android system language list.

For Simplified Chinese, there are zh-Hans-CN, zh-Hans-MO, zh-Hans-HK, and zh-Hans-SG. The previous exact match may not cover other Chinese variants, such as zh-Hans-SG. Please forgive me for using startsWith for fuzzy matching. To ensure no Chinese variant fallback to English.

Based on the reference, Android 7+ and iOS 9+ have started using zh-Hans / zh-Hant language codes, so this patch is also effective for iOS.

Reference:
https://stackoverflow.com/questions/44714408/android-simplified-chinese-and-traditional-chinese-not-working
https://developer.apple.com/library/archive/technotes/tn2418/_index.html

Copy link
Collaborator

@gaearon gaearon left a comment

Choose a reason for hiding this comment

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

looks reasonable to me, thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants