Internationalization of HTML pages for my Google Chrome Extension Internationalization of HTML pages for my Google Chrome Extension google-chrome google-chrome

Internationalization of HTML pages for my Google Chrome Extension


What you would do is this.

First, in your HTML use the same syntax as Chrome requires anywhere else. So your basic popup.html will be:

<!DOCTYPE html><html><head><title>__MSG_app_title__</title></head><body><a href="http://example.com/" title="__MSG_prompt001__">__MSG_link001__</a><!-- Need to call our JS to do the localization --><script src="popup.js"></script></body></html>

Then provide the usual translation in _locales\en\messages.json:

{    "app_title": {        "message": "MyApp",        "description": "Name of the extension"    },    "link001": {        "message": "My link",        "description": "Link name for the page"    },    "prompt001": {        "message": "Click this link",        "description": "User prompt for the link"    }}

And finally your popup.js will perform the actual localization:

function localizeHtmlPage(){    //Localize by replacing __MSG_***__ meta tags    var objects = document.getElementsByTagName('html');    for (var j = 0; j < objects.length; j++)    {        var obj = objects[j];        var valStrH = obj.innerHTML.toString();        var valNewH = valStrH.replace(/__MSG_(\w+)__/g, function(match, v1)        {            return v1 ? chrome.i18n.getMessage(v1) : "";        });        if(valNewH != valStrH)        {            obj.innerHTML = valNewH;        }    }}localizeHtmlPage();


Plain an simple:

{  "exmaple_key": {    "message": "example_translation"  }}
<sometag data-locale="example_key">fallback text</sometag>
document.querySelectorAll('[data-locale]').forEach(elem => {  elem.innerText = chrome.i18n.getMessage(elem.dataset.locale)})


Building from ahmd0's answer. Use a data attribute to allow a hard-coded fallback.

<!DOCTYPE html><html>    <head>        <title data-localize="__MSG_app_title__">My Default Title</title>    </head>    <body>        <a href="http://example.com/" title="__MSG_prompt001__" data-localize="__MSG_link001__">Default link text</a>        <script src="localize.js"></script>    </body></html>

Then provide the usual translation in _locales\en\messages.json:

{    "app_title": {        "message": "MyApp",        "description": "Name of the extension"    },    "link001": {        "message": "My link",        "description": "Link name for the page"    },    "prompt001": {        "message": "Click this link",        "description": "User prompt for the link"    }}

And finally your localize.js will perform the actual localization:

function replace_i18n(obj, tag) {    var msg = tag.replace(/__MSG_(\w+)__/g, function(match, v1) {        return v1 ? chrome.i18n.getMessage(v1) : '';    });    if(msg != tag) obj.innerHTML = msg;}function localizeHtmlPage() {    // Localize using __MSG_***__ data tags    var data = document.querySelectorAll('[data-localize]');    for (var i in data) if (data.hasOwnProperty(i)) {        var obj = data[i];        var tag = obj.getAttribute('data-localize').toString();        replace_i18n(obj, tag);    }    // Localize everything else by replacing all __MSG_***__ tags    var page = document.getElementsByTagName('html');    for (var j = 0; j < page.length; j++) {        var obj = page[j];        var tag = obj.innerHTML.toString();        replace_i18n(obj, tag);    }}localizeHtmlPage();

The hard-coded fallback avoids the i18n tags being visible while the JavaScript does the replacements. Hard-coding seems to negate the idea of internationalisation, but until Chrome supports i18n use directly in HTML we need to use JavaScript.