translation files were kept in /js/bundle folder in .properties files with the default English values in Messages.properties:

1

2

3

4

books-search-text=ISBN/Title/Author

book-retrieve-error=Error on retrieve book:APIrespondedwith{0}!

...

and the actual translation logic was in a common function:

1

2

3

4

5

6

7

8

importi18n from'i18n';

exportdefault{

localize:function(key){

returnjQuery.i18n.prop.apply(jQuery.i18n,arguments);

}

};

that took the key and the dynamic values used in the translations for that key. An actual example on how I used it is:

1

2

3

localizer.localize('books-search-text');

localizer.localize('book-retrieve-error',error.response.status);

After I migrated my project completely to React, I wanted to get rid of jQuery.i18n.properties and jQuery and use something different. The first obvious choice was React Intl since it is one of the most used i18n solutions in React but I did not like it because it looked like that I had to change too much to accommodate it. I wouldn’t mind if the replacement had a completely different way to initialize itself but my expectations for the new library were:

to have support for .properties file, I just didn’t want to use a different format.

to have a similar way to use load translations so that I had to change only the localize function and everything else kept as it is.

The first library that appeared to have this was i18next and the steps are below.

backend – I chose to load resources asynchronously because of the possibility to keep the name and the content of files unchanged.

loadPath – It can be a string or a function with the language the first parameter. The second parameter is the namespace but since I’m not using it in my project, I omited it. I chose to use the function just to be able to make a difference between English, with the default Messages.properties file, and the rest of the locales that have the locale as the file suffix name like Messages_ro.properties.

parse – A function that receives the content of the file and returns an object that has the file keys mapped as the object properties and the file translations mapped as the object properties values. Default format for i18next property files is json so I had to write a small utility, PROP.js, that does a similar job as JSON JavaScript object.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

exportdefault{

parse:function(properties){

returnproperties.split('\n')

.filter(line=>''!==line.trim())

.map(line=>line.split('='))

.map(tokens=>({

[tokens[0]]:tokens[1]

}))

.reduce((properties,property)=>({

...properties,

...property

}),{})

}

};

lng – Language to use.

fallbackLng – Language to use if translations in user language are not available.

interpolation – Configuration used to diferentiate between regular text and dynamic values placeholders. Since in jQuery.i18n.properties I used something like {0} I had to override default configurations for prefix and suffix.