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:
- 27% of the world's population speaks English. source: Wikipedia
- 34% of the world's population has internet access. source: .internetworldstats.com
- Coincidentally, it also seems that the English speaking internet users also make up 27% of the global internet users. source: internetworldstats.com
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?
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.