[client] Only offer locales listed in _index.json (#8091)

This commit is contained in:
Edward
2026-10-06 17:00:21 +02:00
committed by GitHub
parent 51a9d32cfc
commit d3d27dc08d
+19 -4
View File
@@ -40,14 +40,29 @@ function detectBrowserLanguage(available: string[]): string | null {
return null;
}
// An empty persisted language code is the Go-side signal for first run.
// Only locales listed in _index.json are shipped. A bundle on disk without an
// _index.json row (e.g. a new Crowdin language not released yet) must not be
// auto-detected or loaded, matching the Go side, which rejects saving it.
async function shippedLanguages(): Promise<string[]> {
const onDisk = Object.keys(resources);
try {
const listed = new Set<string>((await I18n.Languages()).map((l) => l.code));
return onDisk.filter((code) => listed.has(code));
} catch (e) {
console.warn("load shipped languages failed, using all bundled locales", e);
return onDisk;
}
}
// An empty persisted language code is the Go-side signal for first run. A
// persisted code that is no longer shipped is treated the same way.
export async function initI18n(): Promise<void> {
const available = Object.keys(resources);
const available = await shippedLanguages();
let language = "en";
let firstRun = false;
try {
const prefs = await Preferences.Get();
if (prefs?.language) {
if (prefs?.language && available.includes(prefs.language)) {
language = prefs.language;
} else {
firstRun = true;
@@ -68,7 +83,7 @@ export async function initI18n(): Promise<void> {
fallbackLng: "en",
defaultNS: "common",
ns: ["common"],
resources,
resources: Object.fromEntries(available.map((code) => [code, resources[code]])),
interpolation: {
prefix: "{",
suffix: "}",