For every developer, this day happens. When your application should be translated for another group of users and this group of users — another speaking language.

This process named as “Internationalization” or usually used term “i18n” where 18 stands for the number of letters between the first i and the last n.

In software development this problem is not new. And it’s solved several times in different approaches. But in comparatively young JavaScript world this problem is new and there are many approaches that are very easy and fast to implement, but most of them are hard to support.

When you try to google first ? When you do not know how to specific problem being solved before, isn’t you google it first ? ;-)

Here is the first link from SO https://stackoverflow.com/questions/4717475/how-to-translate-into-other-languages-my-web-page

It offers you to use approach with simple objects where key is a translated phrase and value is translated text.

// JSON-formatted, potentially read from a database

var article = {

title: {

en_US: "Article Title",

fr_FR: "Titre de l\'Article"

},

content: {

en_US: "Content of the Article.",

fr_FR: "Contenu de l\'Article."

}

}



// simple function to write the info to the page

function get_i18n(item, lang) {

document.write(article[item][lang]);

}

Then you just use get_i18n('title') function later where you need to place translated “title”.

This is easy approach but when app grows , and i.e. you need to add new language, you will have to open every file you used this approach and add new translations. Not very fast huh ?

Happily today in JS world we can start using a tool that is being used for software translation for years.

It’s “GetText” https://en.wikipedia.org/wiki/Gettext

It exists since 1990 and still alive. Seems good argument to use.

Thanks to author that made gettext available to use in JavaScript. We use https://github.com/ojii/gettext.js

Our JavaScript code with translated phrases to be translated now looks like this:

import English from 'locales/en/LC_MESSAGES/messages.mo'; import English from 'locales/en/LC_MESSAGES/messages.mo'; class Translate { getLang() { // here you return English or German translation file

}

} const translate = new Translate;

const lang = translate.getLang(); lang.gettext('hello world');

In every place where we need to translate phrase we just write lang.gettext('phrase to be translated') and it returns correct translation for a given lang variable.

Now we have a gettext tool to pull all phrases to be translated from our code automatically. From my root directory I run next:

find src/ -name '*.js' | xargs xgettext --language=JavaScript -o src/lang/locales/de/LC_MESSAGES/messages.po -j

This will scan my src directory for functions with name gettext and save all phrases into messages.po file . That is just simple text file.

# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. "Project-Id-Version: PACKAGE VERSION

" "Report-Msgid-Bugs-To:

" "POT-Creation-Date: 2018-06-26 08:33+0300

" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE

" "Last-Translator: FULL NAME <EMAIL@ADDRESS>

" "Language-Team: LANGUAGE <LL@li.org>

" "Language:

" "MIME-Version: 1.0

" "Content-Type: text/plain; charset=CHARSET

" "Content-Transfer-Encoding: 8bit

" msgid "hello world" msgstr "hallo welt"

This is it. Once you finish with editing po file. You need to use gettext one more time to create a binary translation file that is shorter and can be included into your JavaScript application.

msgfmt src/lang/locales/de/LC_MESSAGES/messages.po -o src/lang/locales/de/LC_MESSAGES/messages.mo

This is it.