caprover-frontend
caprover-frontend copied to clipboard
I want to internationalize this project so that it supports Other language
If you agree, I will submit pr
@githubsaturn
May I ask what you think of that?
Hi @CaryTrivett - thanks for reaching out!
Can you please outline how you plan to do it? Will you be creating a list of strings and replace all embedded strings to reference them?
Hi @CaryTrivett - thanks for reaching out!
Can you please outline how you plan to do it? Will you be creating a list of strings and replace all embedded strings to reference them?
before
<div>CapRover Login</div>;
after
1. use localize
function to replace all text
<div>{localize('caprover.login', 'CapRover Login')} </div>
2. use script to parse all text, and generate en-US.json
file
{
"caprover.login": "CapRover Login"
}
Then translate en-US.json
into other languages, for example zh-CN.json
{
"caprover.login": "CapRover 登录"
}
3. use 'i18next' to load messages
- By default, language gets from localstorage.
- If it doesn’t exist, fetch the language from navigator.language.
- Add a new select in the page, after user chooses, it’s stored in localstorage.
import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
import enUS from 'en-US.json';
import zhCH from 'zh-CN.json';
const resources = {
en: enUS,
zh: zhCH,
};
i18n.use(initReactI18next).init({
resources,
lng: 'en',
interpolation: {
escapeValue: false,
},
});
export default i18n;
Perfect! Looks like a good approach! Thanks for thorough comment. A few thoughts:
1- I see you're using a default value inline - which is exactly what we define in EN:
<div>{localize('caprover.login', 'CapRover Login')} </div>
What's the point of this duplication? Can we just not use the English variant if the selected variant isn't available?
2- Generally speaking, I don't see the value of i18next
here. What prevents us from just something as simple as this?
function localize(key:string) {
const lang = localStorage.language || navigator.language || navigator.userLanguage || 'en';
return resources[lang][key] || resources['en'][key]
}
This has many advantages
- source code as a single trusted data source, when coding only need to write the source code, do not need to change several files
- use ast to parse the source code and generate multi-language configurations to prevent spelling mistakes.
- When reviewing the code, You can see the message at review time, not just the key.
https://github.com/hamsterbase/hamsterbase-highlighter/blob/2c8cb0e732535955d06db115bb5924f1608421a2/src/hamsterbase-highlighter/locales/nls.ts
It's fine to not use third party libraries, that's what I did before
https://github.com/hamsterbase/hamsterbase-highlighter/blob/2c8cb0e732535955d06db115bb5924f1608421a2/scripts/format.mts
This is a parsing script I developed
Oh I see! I misunderstood how this works. Just to make sure my understanding is correct:
1- You write this in the code <div>{localize('caprover.login', 'CapRover Login')} </div>
2- The build process automatically generates en.json etc...
3- You can manually override any strings in translations
Oh I see! I misunderstood how this works. Just to make sure my understanding is correct: 1- You write this in the code
<div>{localize('caprover.login', 'CapRover Login')} </div>
2- The build process automatically generates en.json etc... 3- You can manually override any strings in translations
yes
Sounds good! Feel free to start with a small PR (perhaps just the login page). So that we can see how this is implemented and how it works.
Just curious how the other language will work with One-Click-Apps?
Do you plan to only translate the frontend or all Caprover's project?