SiteKickr Web Development

Going global with JavaScript language translations

Every computer language out there, including JavaScript, has built-in internationalization capabilities, that is, the ability to translate language in order to produce a multilingual application. Can we say translate('english', 'my multilingual JS app')? Not quite. But we have data types at our disposal which make the job a lot easier than it sounds. In it's most basic form, language translation consists of a mapping of one word to another. In JavaScript a mapping is synonymous with an object and it's properties. Before I explain how to create a complete, albeit basic, language translation object in JavaScript, let's look at the stats:

For many of us, including myself, this is an alarming figure. It means that 73% of human beings on the internet are baffled when looking at your website or app!

Granted, these statistics may not take into account English as a second language and many other "micro-stats". But, let's not pick at the accuracy of the statistic, and instead agree that if our website is English-only, it is unusable to very large number of internet users.

Getting the User's Language

To start, we need to be able to determine what the user's current language is. This information is available to JavaScript via the navigator object, but not all browsers implement it the same way.

Internet Explorer makes the browser language available via the navigator.browserLanguage() function. Other browsers provide the navigator.language() function.

How is the Language Returned

We get, in return an ISO 639-1 formatted language code, along with a country code.

For example, for English language users in the US, the returned value would be: en-US.

How can I test different languages?

I've actually found testing to be easiest within the Chrome browser. You are able to change the value returned by navigator.language simply by updating the browser settings as follows:

Settings -> Advanced -> Languages -> Language and input settings...

Be sure to click the button labelled "Display Google Chrome in this language" before closing the window.

I'm not a linguist, how do I translate my text?

For single words, use Google Translate. For anything more, try a translation service, such as One Hour Translation. At time of writing, they are advertising just $.07/word to translate to given language.

 

The Code

The most basic language translation object, as stated above, involves mapping a word in one language, to a word in another language. You might refer to it as the key/value method. In the example below, we use English as the base language, that is, the keys are English words.

I've created a simple translation object for the Spanish language (ISO code: es), mapping eight English words to their Spanish equivalent using a simple JavaScript object.

Everything is wrapped nicely inside a lang object, which contains a property to determine the user's language, the actual word mapping, and a small function to take care of the translation itself.

If a language does not exist in the object, the original word is returned. Similarly, if a language does exist, but a translation isn't available for the provided word, the original word is returned. This is the expected behavior of a translation function, as we would not want a blank space to be inserted in place of a word which there is no translation for.

And finally, instead of calling lang.translate() each time we need a translation, we "clone" this function under the name _ (underscore). This will allow us to perform translations without "mucking up" the code, i.e.

var timeLeft = '5 ' + _('days');

 

Okay, okay, the actual code!

lang = {
    language: (navigator.language || navigator.browserLanguage).split('-')[0],
    translation: {
        'es' : { minute: 'minuto', minutes: 'minutos', second: 'segundo', seconds: 'segundos',
                    hour: 'hora', hours: 'horas', day: 'día', days: 'días' }
    },   
    translate: function(word, language) {
        if (!language) {
            language = lang.language;
        }
       
        if (typeof lang.translation[language] === 'undefined') {
            return word;
        }
       
        if (typeof lang.translation[language][word] === 'undefined') {
            return word;
        }
       
        return app.lang.translation[language][word];
    }
}

// create a shorthand function for language translation
_ = lang.translate;

I've employed this technique in a very basic timer application I created a long time ago, but just recently decided to make it global.