Localization Aware Web Application Using NodeJS

Engineering Feb 04, 2019

It is very common to find websites that are now available in multiple languages. Global brands have now recognized that the only way to connect and create value is by introducing their business to locals in the language that is truly local.

What is Localization in Node JS?

This process of adapting a product to a different language, region and locale is called localization. A localized product creates more business opportunities and caters for growth and expansion. However, many organizations make the mistake of adapting localization towards the end of the development process or just before the product launch.

In order to localize a product, it is very important to find out if it is internationalized.

In this article, we would build a simple website with express and ejs. It has two languages supported (English and Chinese).

Node i18n Support

What Is i18n?

i18n  is a light-weight i18n translation module for NodeJs. It supports dynamic JSON storage and different node template engine.

Internationalization (i18n) is the process of preparing software so that it can support local languages and cultural settings.

What Is Express?

Express provides a minimal interface for NodeJS. It provides the tools that are required to build our app. Using a framework is optional, we can just build this demo by plain NodeJs.

App Configuration

First, let’s set up our server-side code. We would create an express app and listen on port 8080:

var express require('express');
var app express();

app.set('views', __dirname + '/views');
app.get('/', function(req, res) {
  console.log('Hello i18n');
  res.render('index.ejs');
});

app.listen('3000');

We first require express, then we tell express where to look for our templates files. In this case, I used ejs as the template engine. I like it because it’s syntax is basically HTML with special <% ... %> syntax for embedding code from the server. There are also other (and more popular) template engines you can choose from.

In line 7 we add a route for / and tell it to render index.ejs. Let's create our index.ejs file under /views dir.

<html>
<head>
  <title>node, express and i18n</title>
</head>
<body>
  <h1>Hello i18n</h1>
</body>
</html>

Nothing special here, just plain HTML page. Express guesses what type of template to render by the extension. So when it sees index.ejs it knows it should first pass it through the ejs module to render.

Adding Translation Module

Now, let’s add the i18n functionality. I use i18n-node module. Create another file i18n.js:

var i18n require('i18n');

i18n.configure({
  // setup some locales - other locales default to en silently
  locales:['en', 'iw'],

  // where to store json files - defaults to './locales' relative to modules directory
  directory: __dirname + '/locales',
  
  defaultLocale: 'en',
  
  // sets a custom cookie name to parse locale settings from  - defaults to NULL
  cookie: 'lang',
});

module.exports function(req, res, next) {
  i18n.init(req, res);
  var current_locale i18n.getLocale();
  return next();
};

First, we set up some configurations. By default, the i18n module uses accept-languagerequest header to guess language settings. You can tell it to look for a cookie that contains the language if you want. In this case, I used a cookie named lang. Now, let’s import our newly created module in our server file:

var express require('express');
var i18n require('./i18n');

var app express();

app.set('views', __dirname + '/views');
app.use(i18n);

app.get('/', function(req, res) {
  console.log(res.__('Hello i18n'));
  res.render('index.ejs');
});

app.listen('3000');

In line 7 we add the i18n module as middleware. Make sure you put it before any route is defined. What i18n module does is add a special function called __() to the response object. This function takes care of the translation. We need to add the translation __() method to the view file as well:

<html>
<head>
  <title>node, express and i18n</title>
</head>
<body>
  <h1><%= __('Hello i18n')%></h1>
</body>
</html>

Translation Files

Now when you run the app, notice that i18n creates a folder in a location we previously defined in i18n.js. This folder will contain the translation files. In my case, I have two locales : en and iw so i18n will create two files :

  • locales/en.json
  • locales/iw.json

The format is very simple. A valid JSON file that contains "sentence" : "translation" pairs. The first time we try to GET / i18n will automatically populate the files. Since I am using English in my code, i18n will populate en.json with:

{ "Hello i18n": "Hello i18n" }

I will have to edit iw.json with the translation.

{ "Hello i18n": "שלום i18n" }

Results

Let's check if  everything is working okay. I am using Postman (which kicks ass) to call the server. First let’s make a call with Accept-Language=en  header to see the English version:

Localization in Node JS

Now let’s change the header for Accept-Language=iw:

Localization in NodeJS

Some Notes

  • Use escape \ character if you want to insert problematic characters : __("can\'t do that"). Otherwise nasty things will happen.
  • In express 2.x you need to specifically add __() function to the locals object. Do it by adding the following line just after i18n.init() in the i18n module: res.local('__', res.__);
What’s the biggest thing you’re struggling with right now that we as a technology consulting company can help you with? Feel free to reach out to us at info@jalantechnologies.com. We hope our assistance will help!

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.