An easy to use language loader.
In your public directory, create a {language id}.json
file. That looks like this.
{
"meta.id": "{language id}",
"meta.readable-name": "{human friendly name for this language}",
"my.translation-key": "Translation value in the language for this file"
}
I would recommend making a language handler, to help initialise the package. This is a good example in typescript, that should work in pretty much any framework.
import {Language} from "./translatable";
export default class LanguageHandler {
private static _instance: LanguageHandler;
public static get instance() {return this._instance}
private constructor(public readonly lang: Language) {
LanguageHandler._instance = this;
}
public static async create(language: string) {
switch (language) {
case "en_us": new this(await Language.create("en_us", "/lang/en_us.json"));
// add every language your app supports.
}
}
}
en_us.json
{
"meta.id": "en_us",
"meta.readable-name": "English",
"app.name": "Test Application",
"nav.home": "Home",
"nav.messages": "Messenger"
}
index.tsx
const language = localStorage.getItem('lang') || "en_us";
(async () => {
await LanguageHandler.create(language);
root.render(
<React.StrictMode>
<App/>
</React.StrictMode>
);
})();
in your components/pages
<nav>
<h1>{LanguageHandler.instance.lang.get("app.name")}</h1>
<a href="/">{LanguageHandler.instance.lang.get("nav.home")}</a>
<a href="/messages">{LanguageHandler.instance.lang.get("nav.messages")}</a>
</nav>
I would also recommend putting this into its own component. Since they can get messy. Like this
export default function TranslateableText(props: {children: string}) {
return (
<span>{LanguageHandler.instance.lang.get(props.children)}</span>
)
}
and used like this
<TranslateableText>app.name</TranslateableText>