Translations for Chinese are usually split into zh-hans and zh-hant. After loading them using $.i18n().load(), the only zh interface languages which get a translation are zh-hans and zh-hant. All the others use the value for en.
MediaWiki's defined fallback chain says that zh, zh-cn, zh-my and zh-sg should fall back to zh-hans, and zh-hk, zh-mo and zh-tw should fall back to zh-hant. It is not doing that, which leads to inconsistent behaviour depending on how translations are loaded.
An example which loads zh-hans and zh-hant translations and then prints the value for each zh language code:
$.i18n().load({ "en": { "testkey": "en value" }, "zh-hans": { "testkey": "zh-hans value" }, "zh-hant": { "testkey": "zh-hant value" } }); for (let code of ["zh", "zh-hans", "zh-hant", "zh-cn", "zh-hk", "zh-mo", "zh-my", "zh-sg", "zh-tw"]) { $.i18n().locale = code; console.log(code + ": " + $.i18n("testkey")); }
The output:
zh: en value zh-hans: zh-hans value zh-hant: zh-hant value zh-cn: en value zh-hk: en value zh-mo: en value zh-my: en value zh-sg: en value zh-tw: en value
The output of mw.language.getFallbackLanguageChain();:
- uselang=zh: ['zh', 'zh-hans', 'zh-hant', 'zh-cn', 'zh-tw', 'zh-hk', 'en']
- uselang=zh-cn: ['zh-cn', 'zh-hans', 'zh', 'zh-hant', 'en']
- uselang=zh-hans: ['zh-hans', 'zh-cn', 'zh', 'zh-hant', 'en']
- uselang=zh-hant: ['zh-hant', 'zh-tw', 'zh-hk', 'zh', 'zh-hans', 'en']
- uselang=zh-hk: ['zh-hk', 'zh-hant', 'zh-tw', 'zh', 'zh-hans', 'en']
- uselang=zh-mo: ['zh-mo', 'zh-hk', 'zh-hant', 'zh-tw', 'zh', 'zh-hans', 'en']
- uselang=zh-my: ['zh-my', 'zh-sg', 'zh-hans', 'zh-cn', 'zh', 'zh-hant', 'en']
- uselang=zh-sg: ['zh-sg', 'zh-hans', 'zh-cn', 'zh', 'zh-hant', 'en']
- uselang=zh-tw: ['zh-tw', 'zh-hant', 'zh-hk', 'zh', 'zh-hans', 'en']