Internationalization setup - i18n


#1

One of the problems I had starting with Electron was that I couldn’t find any complete examples on how to easily internationalize my applications. Searching the net quickly shows that there is no shortage of i18n solutions for node, but how do you make it work in Electron?

I’ve found a solution with handlebars templating and the i18n package that I think works great. This is what I do.

The window html code is done as usual and saved to a html file. Strings to be translated are marked as follows:

<p>{{ i18n "Hello world" }}</p>

The main process loads the html file as normal. The window must be hidden during this stage. Otherwise users will see the untranslated markups flickering by for a short moment - not very professional.

The html file has a script that runs when the window onload event is fired. This script does the actual translation. After the translation is complete, the script sends an ipc message to the main process. The main process may then make the window visible.

Strings to be translated are automatically put in one json file for each language. In my example these files reside in a subfolder named locales.

Below are instructions on installing packages and source files for a minimal example.

Install packages

npm install --save handlebars
npm install --save i18n

Contents of main.js

const {app, BrowserWindow, ipcMain} = require('electron');

let win;

function createWindow () {
  win = new BrowserWindow({width: 800, height: 600, show: false});
  win.loadURL(`file://${__dirname}/index.html`);
  win.on('closed', () => {
    win = null;
  });
}

app.on('ready', createWindow);

ipcMain.on("translation-complete", (event, args) => {
    //This will show the sender's BrowserWindow
    BrowserWindow.fromWebContents(event.sender.webContents).show();
});

Contents of index.html

<html>
    <head>
        <meta charset="UTF-8">
        <script src="translate.js" charset="utf-8"></script>
    </head>
    <body>
        <p>{{ i18n "Hello world" }}</p>
    </body>
</html>

Contents of translate.js

window.onload = function(){
  const handlebars = require("handlebars");
  const i18n = require("i18n");
  const ipcRenderer = require("electron").ipcRenderer;

  //Setting up i18n. In this example English and Swedish are supported. Translation files
  //are put in subfolder "locales"
  i18n.configure({
    locales:['en', 'se'],
    directory: __dirname + '/locales'
  });

  //This helper makes the connection between Handlebars and I18n
  //Here Swedish is selected. In a real world application the user should of course be
  //able to choose this.
  handlebars.registerHelper('i18n', function(str){
    return i18n.__({phrase:str, locale:"se"});
  });

  //This replaces the entire document with the translation
  var template = handlebars.compile(document.documentElement.innerHTML);
  document.documentElement.innerHTML = template();

  //Notify main process that the translation is complete
  ipcRenderer.send("translation-complete", null);
};