React-i18next | React-intl | |
---|---|---|
monthly downloads | 6033996 | 4061606 |
Maintainence | Maintained | Maintained |
Relay on external dependencies | 3 | 10 |
Translation function along with plurals, context and interpolation | provided | provided |
support for different framworks | More | Less |
Time and date formatting | provides built in intl API(in latest version) | provides built in intl API |
translation loading mechanism and browser language detection | plugins provided | handle manually |
Auto Extract strings from Js and put in JSON | plugin provided | plugin provided |
callbacks for untranslated key/values | provided | not provided |
Currenty industry standards are moving toward React-i18next and is more of a swiss army knife, it does many things relatively well and is lightweight as well.
Plugin | Description |
---|---|
react-i18next | A complete solution to localize React based frontend along with passing i18n in complex techniques and components including higher-order components(HOC), hooks, render props etc |
browser language detector | detect language from browser, cookie or from localstorage |
i18next parser | automated extraction of strings present in js. |
backend (if needed) | provides different backends to manage translations and ability to load them dynamically to reduce initial bundle size of translations |
enable use of ICU format with i18next | Enables use of ICU message format in JSON translation files used with i18next |
a. react-i18next b. browser language detector
JSON based file
Per locale single JSON file containing all the translations.
its good practice to use translation directory structure similar to the code files present in the code base. i.e for each code file there is corresponding JSON file holding translation for that particular code file.
For Alby, extension has minimal set of strings to be translated. also demo page is withing website and not in extension itself so per locale we can use only single json file
we can either use http-backend plugin to load translations dynamically or load json file directly by instructing typescript compiler to allow the json file loading.
we are not using multiple translation files for single locale as mentioned above so directly loading translation is the best option
different methods are provided to pass translation function to the component
a. Using hooks
#initialization
const { t, i18n } = useTranslation();
b. Using HOC
# wrap component with the withTranslation() method
export default withTranslation()(MyComponent);
c. Using render prop
<Translation>
{
t => <h1>{t('Welcome to React')}</h1>
}
</Translation>
d. Using trans component
<Trans><H1>Welcome to React</H1></Trans>
depending on the context we can use any of the method
key shall clearly represent the context of the string eg. when translating title string we can name key as .title
which represent the clear context of the string which key holds.
complete key shall be named in such a way so that when translator or any person sees the key present in json file , he/she shall be able to findout that in which code file that particular key belongs
to do so reacti18next provides facility to nest the keys in json file when keySeparator
value is set to true
if filenames are appropriate we can use key naming such as file_name + key_name
eg. ConfirmPayment.title
in our case most of the files present in folder structure are index.tsx. so we can go with folder_name + keyName
eg. ConfirmPayment.title
we can use concept of namespace provided by the library
eg. const { t } = useTranslation('myNamespace');
now use t method as t('key_name')
library will grab the string for that particular namespace only
here namespace can act as folder name and in translation function we are free to use key-name only without doing any separation of keys
for typescript>4.1 we need additional config inorder to achieve full type safety for t function https://react.i18next.com/latest/typescript
local switcher will hold drop down representing native language name , in background language names are mapped with locale, selection of any language will set the corresponding locale of the selected language.
local shall be persisted when user refreshes the page, and navigate to any other page/component
this can be easily done by removing lang: "en"
in the init configuration of i18next and locale will be persisted accross routes and page refreshes using browser language detector plugin. lang attribute just overrides the behaviour of language detector plugin. so removing lang attribute and using plugin helps to persist the locale
i18n.language
once set , persists locale for newer sessions. i.e if user sets locale to :el and then closes alby and then comes back again, content will be in :el and not in default or fallback language. this is also done by detector plugin. i18n.language will detect the locale using following flow
https://react.i18next.com/legacy-v9/step-by-step-guide#c-auto-detect-the-user-language
for testing purpose its good to have alternate language running in parallel with english language while doing i18n for project
As an alternate language i can speak Hindi
:hi , i can translate alby to :hi or if translators are provided i can pass translation files created to the translators for performing translations.
We can use Weblate setup but currently in perspective of initial i18n setup, we must focus more on above mentioned i18n rules and conventions and maintain consistency in i18n throughout the codebase so unless i18n is set up completely its not much required