Closed auroursa closed 3 days ago
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
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:This cannot be matched to existing
AppLanguage
, so it will rollback to English. BecauseAppLanguage
naming follows RFC 1766, which is still widely used in browsers. Therefore, we cannot rename ChineseAppLanguage
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:Based on #5384, the app can now correctly handle language tags with region codes. This allows it to match the existing
zh-CN
inAppLanguage
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.
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:
https://github.com/user-attachments/assets/fc8dda1d-0099-47a7-a6c2-4772bbfe2cf3
After:
https://github.com/user-attachments/assets/8169186c-a71f-4a7d-91f1-d8845b1fc514