Browse Source
There are two problems with the current localization strategy: - We download the translations on-demand, which means that it does a serial roundtrip for nothing. - withTranslation helper actually renders the app 3 times on startup, instead of once (I haven't tried to debug it)pull/640/head
21 changed files with 100 additions and 166 deletions
@ -1,36 +1,68 @@
@@ -1,36 +1,68 @@
|
||||
import i18n from "i18next"; |
||||
import { initReactI18next } from "react-i18next"; |
||||
|
||||
import Backend from "i18next-xhr-backend"; |
||||
import LanguageDetector from "i18next-browser-languagedetector"; |
||||
|
||||
export const fallbackLng = "en"; |
||||
export const languages = [ |
||||
{ lng: "en", label: "English", data: require("./locales/en.json") }, |
||||
{ lng: "de", label: "Deutsch", data: require("./locales/de.json") }, |
||||
{ lng: "es", label: "Español", data: require("./locales/es.json") }, |
||||
{ lng: "fr", label: "Français", data: require("./locales/fr.json") }, |
||||
{ lng: "pt", label: "Português", data: require("./locales/pt.json") }, |
||||
{ lng: "ru", label: "Русский", data: require("./locales/ru.json") }, |
||||
]; |
||||
|
||||
let currentLanguage = languages[0]; |
||||
const fallbackLanguage = languages[0]; |
||||
|
||||
export function setLanguage(newLng: string | undefined) { |
||||
currentLanguage = |
||||
languages.find(language => language.lng === newLng) || fallbackLanguage; |
||||
|
||||
languageDetector.cacheUserLanguage(currentLanguage.lng); |
||||
} |
||||
|
||||
export function getLanguage() { |
||||
return currentLanguage.lng; |
||||
} |
||||
|
||||
export function parseDetectedLang(lng: string | undefined): string { |
||||
if (lng) { |
||||
const [lang] = i18n.language.split("-"); |
||||
return lang; |
||||
function findPartsForData(data: any, parts: string[]) { |
||||
for (var i = 0; i < parts.length; ++i) { |
||||
const part = parts[i]; |
||||
if (data[part] === undefined) { |
||||
return undefined; |
||||
} |
||||
data = data[part]; |
||||
} |
||||
return fallbackLng; |
||||
if (typeof data !== "string") { |
||||
return undefined; |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
export const languages = [ |
||||
{ lng: "de", label: "Deutsch" }, |
||||
{ lng: "en", label: "English" }, |
||||
{ lng: "es", label: "Español" }, |
||||
{ lng: "fr", label: "Français" }, |
||||
{ lng: "pt", label: "Português" }, |
||||
{ lng: "ru", label: "Русский" }, |
||||
]; |
||||
export function t(path: string, replacement?: { [key: string]: string }) { |
||||
const parts = path.split("."); |
||||
let translation = |
||||
findPartsForData(currentLanguage.data, parts) || |
||||
findPartsForData(fallbackLanguage.data, parts); |
||||
if (translation === undefined) { |
||||
throw new Error("Can't find translation for " + path); |
||||
} |
||||
|
||||
if (replacement) { |
||||
for (var key in replacement) { |
||||
translation = translation.replace("{{" + key + "}}", replacement[key]); |
||||
} |
||||
} |
||||
return translation; |
||||
} |
||||
|
||||
const languageDetector = new LanguageDetector(); |
||||
languageDetector.init({ |
||||
languageUtils: { |
||||
formatLanguageCode: function(lng: string) { |
||||
return lng; |
||||
}, |
||||
isWhitelisted: () => true, |
||||
}, |
||||
checkWhitelist: false, |
||||
}); |
||||
|
||||
i18n |
||||
.use(Backend) |
||||
.use(LanguageDetector) |
||||
.use(initReactI18next) |
||||
.init({ |
||||
fallbackLng, |
||||
react: { useSuspense: false }, |
||||
load: "languageOnly", |
||||
}); |
||||
|
||||
export default i18n; |
||||
setLanguage(languageDetector.detect()); |
||||
|
||||
Loading…
Reference in new issue