Neverending Pile of Messages


    0.6.1 • Public • Published


    Build Status NPM version


    • Full featured localization module for express.js
    • server side translation
    • Pluggable storages
    • Pluggable strategies like query, path, cookie ect.
    • Url Translation
    • Uses common __('...') syntax in app and templates
    • Support for plurals
    • Stores language files in json files compatible to webtranslateit json format
    • Adds new strings on-the-fly when first used in your app
    • Nested, hierarchical contexts, separated in different files
    • Uses the closest to the preferred user locale, if not set explicitely by the user request
    • Automatic fallback to more generic localization (
    • Support for locale names according to
    • No extra parsing needed.
    • Handles simultaneous requests with different locales correctly :-)


    The module was originally developed by, then forked and refactored by This is a serious refactoring of the latter. Reasons:

    • were not pluggable / extendable
    • not specific to express.js
    • complicated code
    • features missing: url translation, hierarchical contexts, locale fallback, preferred user locale, ...


    • better description
    • more tests
    • client side translation / routes
    • import/export language definitions e.g. gettext


    Run the following:

    npm install loc


    Load and Configure

    In your app.js:

    // example localization initialization
    var loc = require('loc')({
    	// it gets the locale from the following strategies in this order.
    	// if the locale is not part of the `path`it looks it up in the `query` ect.
      getLocaleFrom: ['path', 'query', 'subdomain', 'cookie'],
      // if the locale was found in one of the strategies above, it stores it with this strategy.
      // in this case in the `cookie`
      storeLocaleTo: ['cookie'],
      // the locale definitions (translations) are retrieved from `file`.
      storage: 'file',
      // the following locales are supported (optional). 
      // If this option is omitted, it accetps what ever is defined in the definitions.
      locales: ['de', 'de-ch', 'en', 'en-GB', 'en-us'],
      // locale definition director
      directory: "./locales",
      // locale definition file extension
      extension: ".json",
      // Exclude List for the path rewrite middleware used for the path strategy.	
      // problematic are static assets and url's that start with one to three letters in the path like:
      // /p/, /js/ or /img/ and should therefore be excluded.
      excludeList: [".css", ".js", '.ico', '/api/', '/img/', '/css/', '/js/']
    // adds all middlewares as bundle
    //or add them separately
    // adds the loc middleware. adds the req.i18n object.
    // adds the locPathRewrite middleware used for the `path` strategy.
    // it redirects the request to the url without the locale in the path. e.g. `/en-GB/about` to `/about` 
    // adds the urlTranslation middleware
    // print out localeCache for debugging purposes 

    Inside Your Express View

    module.exports = {
    	index: function(req, res) {
    		req.render("index", {
    			title: req.i18n.__("My Site Title"),
    			desc: req.i18n.__("My Site Description")

    Inside Your Templates: Swig example

    {% extends "page.swig" %}
    {% block content %}
    <h1>{{ __("Welcome to:") }} {{ title }}</h1>
    <p>{{ desc }}</p>
    {% endblock %}

    Inside Your Templates: ejs example

      <title><%=__("title") %></title>

    locale definition

    An example locale definition en.js inside ./locales/ may look something like:

    	"Hello": "Hello",
    	"Hello %s, how are you today?": "Hello %s, how are you today?",
    	"weekend": "weekend",
    	"Hello %s, how are you today? How was your %s.": "Hello %s, how are you today? How was your %s.",
    	"Hi": "Hi",
    	"Howdy": "Howdy",
    	"%s cat": {
    		"one": "%s cat",
    		"other": "%s cats"
    	"There is one monkey in the %%s": {
    		"one": "There is one monkey in the %%s",
    		"other": "There are %d monkeys in the %%s"
    	"tree": "tree"

    that file can be edited or just uploaded to webtranslateit for any kind of collaborative translation workflow.

    locale definition with contexts example

    Source Files

    // locales/en.json
    	"Home": "Start Page",
    	"Lessons": "Lessons",
    	"About Us": "About Us"
    // locales/de-ch.json
    	"Home": "De Hei",
    	"Lessons": "Lektion",
    	"About Us": "Über üüs"
    // locales/url/de-ch.json
    	"title": "Tegscht"
    // locales/url/cms/de-ch.json
    	"cms title": "CMS Überschrift",
    	"nested": {
    		"keys": "Verschachtelt"


    var loc = require('loc')();
    var i18n = new Translation(loc);
    // Example 1
    // Example 2
    i18n.t('url/cms/cms title')
    // Example 3
    i18n.t('url/cms/nested.cms title')

    Queries (internal)

    // Example 1
    // locale sep   key        Resulting Value
    //  ----  ---  ------      ---------------
    // ['en']['/']['Home'] --> "Start Page"
    // Example 2
    //  locale     context     sep     key            Resulting Value
    //  -------  ------------  ---  -----------      -----------------
    // ['de-ch']['url']['cms']['/']['cms title'] --> "CMS Überschrift"
    // Example 3
    //  locale     context     sep       key              Resulting Value
    //  -------  ------------  ---  ----------------      ---------------
    // ['de-ch']['url']['cms']['/']['nested']['keys'] --> "Verschachtelt"

    localeCache (internal)

    	"en": {
    		"Home": "Start Page",
    		"Lessons": "Lessons",
    		"About Us": "About Us"
    	"de-ch": {
    		"/": {
    			"Home": "De Hei",
    			"Lessons": "Lektion",
    			"About Us": "Über üüs"
    		"url": {
    			"/": {
    				"title": "Tegscht"
    			"cms": {
    				"/": {
    					"cms title": "CMS Überschrift",
    					"nested": {
    						"keys": "Verschachtelt"

    url translate

    if the url translation middleware is added: app.use(loc.urlTranslation()); Urls will be translated according to the context url. The url is being translated by segments.

    Example: File: locales/de-ch.json { "Start" : "home", "Seite": "page" }

    • the url: /Start is being redirected to /home
    • the url: /Start?Seite=1 is being redirected to /home?page=1


    In order to run the following examples, you must first require loc and create a new i18n object. The i18n object is created on every request.

    var loc = require('loc')();
    var i18n = new Translation(loc);

    __(string, [...])

    Translates a string according to the current locale. Also supports sprintf syntax, allowing you to replace text, using the node-sprintf module.

    For example:

    var greeting = i18n.__('Hello %s, how are you today?', 'Marcus');

    this puts Hello Marcus, how are you today?. You might also add endless arguments or even nest it.

    var greeting = i18n.__('Hello %s, how are you today? How was your %s?', 
    	'Marcus', i18n.__('weekend'));

    which puts Hello Marcus, how are you today? How was your weekend?

    You might even use dynamic variables. They get added to the current locale file if they do not yet exist.

    var greetings = ['Hi', 'Hello', 'Howdy'];
    for (var i = 0; i < greetings.length; i++) {
    	console.log( i18n.__(greetings[i]) );

    which outputs:


    __n(one, other, count, [...])

    Different plural forms are supported as a response to count:

    var singular = i18n.__n('%s cat', '%s cats', 1);
    var plural = i18n.__n('%s cat', '%s cats', 3);

    this gives you 1 cat and 3 cats. As with __(...) these could be nested:

    var singular = i18n.__n('There is one monkey in the %%s', 'There are %d monkeys in the %%s', 1, 'tree');
    var plural = i18n.__n('There is one monkey in the %%s', 'There are %d monkeys in the %%s', 3, 'tree');

    putting There is one monkey in the tree or There are 3 monkeys in the tree.


    Returns a string containing the current locale. If no locale has been specified then it default to the value specified in defaultLocale.


    Sets a locale to the specified string. If the locale is unknown, the locale defaults to the one specified by defaultLocale. For example if you have locales of 'en' and 'de', and a defaultLocale of 'en', then call .setLocale('ja') it will be equivalent to calling .setLocale('en').


    To be used with Express.js or another framework that provides a request object. This method works if a request option has been specified when the i18n object was instantiated.

    This method returns true if the locale specified by getLocale matches a language desired by the browser's Accept-language header.


    run the tests with



    • v0.6.0: express 4 support


    MIT License


    npm i loc

    DownloadsWeekly Downloads






    Last publish


    • andineck