While working on a HTML5 project I came across the problem that I needed to localize it to different languages. Therefore obviously strings of HTML tags as well as JavaScript files need to be translated.
Although I think internationalization is something very important in a globally connected world, it looks like as this topic was completely forgotten for HTML5 development. I just found a proposal in the Common JS Wiki regarding that with no activity since more than a year!
After searching for while I found this post about Passive localization in JavaScript. Of course, I would prefer an officially standardized approach for the localization, but anyway, this JavaScript library is very helpful to use in the meantime until there is an an officially standardized solution.
In the following I will explain how I use this library, not only for JavaScript files, but also for translating the content of HTML tags.
HTML5 Test Page
First of all we need a small HTML5 test page like this:
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<title>Internationalization Test</title>
<link rel="localization" hreflang="de" href="lang/de.json" type="application/vnd.oftn.l10n+json"/>
<link rel="stylesheet" href="css/style.css">
<script type="text/javascript" src="js/i18n.js"></script>
<script type="text/javascript" src="js/script.js"></script>
</head>
<body onload="loaded()">
<h1 id="headertext">This is an Internationalization Test!</h1>
<h2 id="subtitletext">With any subtitle.</h2>
<a id="showinenglish" href="index.html?lang=en">Show in English</a>
<a id="showingerman" href="index.html?lang=de">Show in German</a>
</body>
</html>
You can see that I assigned IDs to all major HTML tags. We will use them later on for doing the translation.
JavaScript Helper Functions
Before starting with the translation itself, we need some JavaScript helper functions first:
var _ = function (string) {
return string.toLocaleString();
};
function localizeHTMLTag(tagId)
{
tag = document.getElementById(tagId);
tag.innerHTML = _(tag.innerHTML);
}
function getParameterValue(parameter)
{
parameter = parameter.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + parameter + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if(results == null)
return "";
else
return results[1];
}
Here is a short explanation about what these helper functions are doing:
_()
: that’s just a short form of the prototype string.toLocaleString()
.
localizeHTMLTag(tagId)
: this function gets the appropriate HTML element from the DOM tree based on the passed tag ID and directly does the translation afterwards.
getParameterValue(parameter)
: we’ll need this function to get a URL parameter value to change the language of the page upon user request.
Doing the Localization
We have all needed parts to do our localization which is really easy now:
function loaded()
{
var lang = getParameterValue("lang");
if (lang != "") String.locale = lang;
alert(_("Localizing the document title..."));
document.title = _(document.title);
alert(_("Localizing other HTML tags..."));
localizeHTMLTag("headertext");
localizeHTMLTag("subtitletext");
localizeHTMLTag("showinenglish");
localizeHTMLTag("showingerman");
alert(_("Localizing done!"));
}
There is just one function loaded()
, which is called after the document is loaded (see the event in body tag of the HTML5 test page above). First we check if there is an URL parameter lang in case the user changed the page language with the links. Otherwise we don’t need to change the locale (the default browser locale of the user will be used automatically).
Afterwards we can start doing our translation by directly translating a string with the function _()
or by using our function localizeHTMLTag(tagId)
to translate the content of a HTML tag. That’s it!
What About More Languages?
If you want to add more or other languages, you just need to add a new localization link in the HTML head section together with a JSON file containing the translations for the new language.
Why not Using Short Variable Names?
The author of this JavaScript internationalization library suggests to use short variable strings instead of the default translations. Therefore I want to give an explanation why I’m not doing this in my example as he is, of course, right that using the default translations adds some overhead to the project. But using short variable names would have at least these two disadvantages, too:
- your HTML5 page would no longer work without a translation, because otherwise only the short variable names would be displayed. In my example project it would just display the default translation (English) when no internationalization system is available.
- I still hope that there will be a standardized way to do internationalization for HTML5 projects. Then probably you will need to have the default translation inside the HTML tags as the de facto standard for doing e. g. translation of PHP projects is to use gettext files (.po). That’s also the way the mentioned proposal suggests to do it. Therefore when I want to switch to such a way of internationalization somewhen in the future, I don’t like to copy all default translations back into the HTML tags.
Download Example Project
If you like, you can download the source of my example project.
Update
I’ve updated the example project as there was one comma too much in the JSON file which caused it to only work in Mozilla Firefox (not in Microsoft Internet Explorer and Google Chrome). That’s fixed now – thanks Margaret Wong for letting me know about that!
But please keep in mind that you have to upload the files to a webserver for testing as they probably won’t work in Internet Explorer and Chrome locally due to browser access restrictions. Anyway, the example project will work fine now when you upload it to a webserver.
What concept you’re using for localizing your HTML5 projects?