Search code examples
reactjsreact-i18next

react-i18next how to translate a given string


I have a React app that uses react-i18next for localization.

I have translated many things like menu titles, button texts etc. But I have some values that are not "hardcoded" per se.

For example, I have something like "Air quality". So I have it translated like

en.tsx

const LocaleEn = {
  airQuality: 'Air quality'
}

pl.tsx

const LocalePl = {
  airQuality: 'Jakość powietrza'
}

Then, I init the i18next "instance" like this:

i18next.use(initReactI18next).init({
  resources: {
    en: {
      translation: LocaleEn,
    },
    pl: {
      translation: LocalePl,
    },
  },
  lng: 'en',
  interpolation: {
    escapeValue: false,
  },
  supportedLngs: ['en', 'pl'],
});

export default i18next;

Then, it's just const {t} = useTranslation() and t('airQuality').

Fairly simple. Now, I want to have a box/div/whatever displaying the "Air Quality" text but also its value. There are two possible values and they are string: GOOD and BAD.

What I came up with is just having something like:

const LocaleEn = {
  airQuality: {
    name: 'Air quality',
    goodValue: 'GOOD',
    badValue: 'BAD'
  }
}

And then I'd do something like:

const airQuality = 'GOOD'
// [...]
<p>{t('airQuality.name')}</p>
<p>{airQuality === 'GOOD'? t('airQuality.goodValue'): t('airQuality.badValue')}</p>

But this is tedious, having this if.

So, my question is: is there a way for react-i18next to receive something like GOOD or BAD and translate it - based on the locale selected? With of course me providing those translations somehow.


Solution

  • Absolutely you can do that.

    The way that I have found most useful to do these translations is having each word inside of your dictionary of a different language.

    By doing translate("GOOD"), If the locale is the default locale, and it is not in that dictionary, it will display the text given. Then inside of your secondary language dictionary, you can make

    "GOOD": ""
    

    a translated value, and when that key is seen, it will use the translated word. That way the dictionary of the other languages are always the english word as a key.

    Then inside of your sample, you can do

    t(airQuality)
    

    Each word, or phrase, should have a corresponding translation in the JSON file for every language that is not the default.

    In this case an example of your JSON might look like this

    const LocalePl = {
       "Air Quality": "Jakość powietrza"
       "GOOD": "[translate]",
       "BAD": "[translate]",
    }
    

    your english translation can be blank.

    Your JSX then would look like this:

    <p>{t("Air Quality")}</p>
    <p>{t(airQuality)}</p>