I am currently implementating internationalization, often abbreviated as i18n, in
a React app I’m working on. I’m using react-i18next
to handle the translations, and I wanted to make sure we had proper test coverage for this new functionality. The way this package works,
which is just a React wrapper around the i18next package, is by mapping nested keys to their associated values
in a particular list of translations. By some means we detect the user’s language (usually from the browser), and fetch the JSON file associated
with those translations and interpolate the values into the key placeholders. For example, for English we fetch the
and use the package-provided
<I18n /> component to translate it. Therefore
will become simply
You need to create a configuration file for initialization of the i18next package, providing various options. Two of these most importantly tell i18next where to find the translation files and how to fetch them. For the actual application’s configuration, I’m fetching the file(s) by way of XHR and a newly created endpoint. However for unit testing, we want both instant translations and to avoid the overhead of making a network request. The documentation provides an example of how to create an i18next configuration file specifically for testing, so I used something very similar to that found here. For this configuration I tried using the i18next-sync-fs-backend in order to instantly load the translations by way of file fetching and reading on the server-side as opposed to an XHR request.
However, this turned out to be quite the headache. It was not translating my strings despite scouring Google, trying to verify the correct file path, etc.
I finally decided to do the importing myself, so using the file system package fs, I fetched and parsed the JSON directly in the configuration file.
i18next provides a function to add the resources as an argument rather than fetching them and handling the file parsing itself. By using
to add the JSON resources and
readFileSync to pull the JSON directly into the config file, I was able to get my translations rendering synchronously and correctly.
My working configuration file looked something like this:
Language values are hard-coded in this example, but you can easily provide those as dynamic arguments for other languages. If you’re like me and struggled to get this working, I hope you can find this useful, or at least learned something new. Thanks for reading!