skip to Main Content

I’m in the progress of internationalizing an node expressjs-app. The idea is to serve the whole website within a language-subfolder (www.domain.com/en/). I’m kinda struggling wrapping my head around how to organize the app and it seems kinda hard to find some useful resources on this issue on stacko or the web in general.

I feel what makes it challenging here, is the fact that you have to achieve the best in three areas: Usability, SEO, and Performance.

There are a couple of questions:

  • Where are the response/selected languages to be stored? In the Session?
  • What is ideally the single source of throuth of the current language setting?
  • How is the language path affecting the language? (Changing the language to current path? Redirect to active/stored language?)
  • How are the routes to be organized? What Middleware strategies make sense for detecting and changing languages? Is it necessary to add to all internal links the language subpath, or can this be done by clever routing?

I would love to get some hints, resources, blog articles, repos where I can learn about best practices on this topic.

Cheers

3

Answers


  1. I can highly recommend i18n for node.js. I have used it in 2 node Projects so far and it always worked like a charm. I then always had one json-File for each language I wanted to serve. You need to implement it once in your templates and then it hsould just work.

    Regarding configuration an easy example:

    // Configuration
    app.configure(function() {
    
        [...]
    
        // default: using 'accept-language' header to guess language settings
        app.use(i18n.init);
    
        [...]
    });
    

    So than i18n will guess the language based on the users browser agent.
    What I am always doing is not using an extra route rather I am using a parameter lang and than it is possible to change the language all the time per hrefs. E.g. https://example.com/?lang=de will change to german language. Of course you need in every get of express a helper function to detect if another language is set and then you can handle that. For me that was the easiest way but regarding SEO that is not the best I think.

    Of course you can also handle it e.g. with different domains/subdomains as airbnb is doing that. https://nl.airbnb.com vs. https://www.airbnb.com vs. https://www.airbnb.de or as you mentioned with routes does also work very well. But I think that is related with a little more work.

    For pros and cons regarding SEO and other you can just google a little bit and have a look at this quora question which also highly recommends the Google Best Practices at this topic.

    Login or Signup to reply.
  2. You don’t even need to use a library for a simple localization. I’ll show you a simple example:

    Let’s say you have your language strings in a json at global scope (can be in a file or db too) :

    var languageData = {
        'en': {
            'LOGIN_BTN': 'Login now',
            'REGISTER_BTN': 'Register'
        },
        'tr': {
            'LOGIN_BTN': 'Giris',
            'REGISTER_BTN': 'Kayit'
        }
    }
    

    Let’s create simple middleware:

    function getLanguageStrings(req, res, next) {
        var lang = req.acceptsLanguages('en', 'tr', 'fr')
        var selectedLang = lang ? lang : 'en' // default to english
        req.languageStrings = languageData[selectedLang]
        next()
    }
    

    Above, I used acceptsLanguages() method to get the preferred language of browser, but you can set cookie from client side and read it in our middleware if you want to.

    With the req.languageStrings = languageData[selectedLang] line, I’ve attached strings to current request so that next middleware can use it.

    Let’s use our middleware:

    app.use(getLanguageStrings)
    

    And in the route, render them to view:

    app.get("/info", function (req, res) {
        res.render("info.html", { 
            languageStrings: req.languageStrings
        })
    })
    

    In view, you now use it with your preferred template engine:

    <button class="btn">{{languageStrings.LOGIN_BTN}}</button>
    <button class="btn">{{languageStrings.REGISTER_BTN}}</button>
    
    Login or Signup to reply.
  3. For this purpose I used i18n module (pretty much the same procedure with other localization modules). You keep your translations in simple json files and by default i18n checks for a language depending on a cookie sent by client.

    That is pretty much it, I think there is a few other ways to get the language instead of using cookies, for example by request params (as you’ve mentioned) or by value sent within request body.

    It really depends on your needs. This is only available if you use i18n-node-2 module, for the first one you have to use cookies (correct me if I’m wrong).

    Example I’ve created to show how to set it up on your server side.

    Localization with Express and i18n

    Update:

    For i18n-node-2

    Like the README.md file says, there is a few functions which you can choose to detect / set needed language:

    • setLocale(locale)
    • setLocaleFromQuery([request])
    • setLocaleFromCookie([request])
    • setLocaleFromSessionVar([request])
    • setLocaleFromEnvironmentVariable()

    Documentation: i18n-node-2

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search