Contactez-nous : 01 71 18 39 72
Suivez-nous sur Facebook

Internationalizing a Javascript script

Lately, while working on Butterflive, I was faced with the challenge of internationalising a pure Javascript module. Using the usual server-side techniques to provide translation was not an option.

Basically, I wanted to easily provide a chat window with messages that would be translated automatically depending on the browser's locale.

After a quick Google search, I realized there was no real out-of-the-box solution that suited my needs. The module that came closer to my needs was the jQuery localisation plugin, but I realised that if the locale was not supported, it would perform a 404 HTTP call to a non-existing resource before falling back to the default translation file. I wanted to avoid 404 calls, so I decided to write my own module, which turned-out to be really easy.

The whole strategy is to write a special Javascript file that contains the translated messages. For Butterflive, this file looks like this:

messages.js (default file in English)

ApiMessages={
	"visitor": "Visitor",
	"me": "Me",
	"chattingwith": "You are now chatting with ",
	"joinedtheroom": " joined the room",
	"disconnectedmsg": "You have been disconnected. Trying to reconnect.",
	"chatsessionclosed": "Chat session closed.",
	"hasbeendisconnected": " has been disconnected.",
	"connecting": "Connecting",
	"waitingforuser": "Waiting for user",
	"mainwindowtitle": "Chat window"
}

The translated version of this file in French:

messages-fr.js

ApiMessages={
	"visitor": "Visiteur",
	"me": "Moi",
	"chattingwith": "Vous êtes maintenant en chat avec ",
	"joinedtheroom": " a rejoint le chat",
	"disconnectedmsg": "Vous avez été déconnecté. Tentative de reconnection.",
	"chatsessionclosed": "Session de chat terminée.",
	"hasbeendisconnected": " a été déconnecté.",
	"connecting": "Connection en cours",
	"waitingforuser": "En attente de l'utilisateur",
	"mainwindowtitle": "Fenêtre de chat"
}

Now, I need to be able to load the correct file. I decided to write a localize function. This function takes in parameter either the name of the language to be loaded (as a 2 characters string), or an array of available languages.

For instance, localize("fr") will force the loading of the messages-fr.js file. Alternatively, localize(["en","fr","de"]) will load one of those 3 language files depending on the browser's locale, or will default to messages.js otherwise.

function localize(language) {
	// If a string is passed in parameter, let's load the file associated.
	if (typeof(language)=="string") {
		loadScript("i18n/messages-"+language+".js");
		return;
	}
 
	// Let's get the browser's language
	var l_lang;
	if (navigator.userLanguage) // Explorer
		l_lang = navigator.userLanguage;
	else if (navigator.language) // FF
		l_lang = navigator.language;
	else
		l_lang = "";
 
	// If the parameter passed is not a string or an array, 
	// or if no browser's language can be found, let's use default file.
	if (typeof(language)!="object" || l_lang == "") {
		loadScript("i18n/messages.js");
		return;
	}
 
	var browserLang = l_lang.substr(0,2);
 
	// If the browser's language is available in the translation files
	// let's use that!
	for (var i=0; i<language.length; i++) {
		if (language[i] == browserLang) {
			loadScript("i18n/messages-"+browserLang+".js");
			return;
		} 
	}
 
	// If no language found, let's load the default language file:
	loadScript("i18n/messages.js");	
};
 
// A simple function to dynamically load a script.
// Please note it uses jQuery (but you can adapt it easily)!
function loadScript(url) {
	var script=document.createElement('script');
	script.type='text/javascript';
	script.src=url;
	$("head").append(script);
	return;
};

That's it! Pretty easy isn't it?