Localization of Sails.js Applications

Sails.js is a popular Node.js MVC framework for web applications. In a recent project, we localized a web application into multiple languages. The Sails.js documentation on this was very useful, but spread over several sections. Here I would like to summarise the actions we took to localize the application.

Add Localization Files

  1. Place files in config/locales

  2. Name the files, with the language code,

    <language code>.json
  3. Files have the format:

         "Welcome": "Welcome",
         "A brand new app.": "A brand new app."

Configure Locales

In file, api/config/i18n.js, set:

  1. set of locales,

    locales: [“en", “de", “pl"]
  2. set default locale,

    defaultLocale: “pl"
  3. In each controller action, where you generate a view, you need to set the locale:

    login: function(req, res){
           // sails.log.debug(req.headers);
           // sails.log.debug(req.getLocale());
           return res.view('login', {});

Use Localization in Views

Enclose the term as in the example:

<%= __("Error!") %>

Localization of JavaScript in Views

We use jQuery.i18n.

  1. Create translations, say in folder assets/translations

  2. The file format is like the Sails.js localization files,

           "Fill_your_username_and_password" : "Fill your username and password",
           "Wrong_username_or_password" : "Wrong username or password",
  3. Load locales in views,

    $.i18n().load( {
          en: '/translations/alerts_en.json',
          de: '/translations/alerts_de.json'
             $.i18n( {
                  locale: ‘de' // Locale is German
             // use translations, for example
             var noneSelected = $.i18n('SelectAtLeastOne');

Localize Validation Messages in Forms

We need to prevent the default browser validation messages, and localize the error messages.

For each input HTML element, we use setCustomValidity on the oninvalid trigger, with a localized error message,

  oninvalid="this.setCustomValidity('<%= __('An email is required') %>')"

And the full input element is:

    <input required





        placeholder="<%= __('Email') %>"

        oninvalid="this.setCustomValidity('<%= __('An email is required') %>')"