Multi-language routes in express.js?

后端 未结 5 1456
终归单人心
终归单人心 2020-12-29 07:30

I\'m wondering if there is a best practise example on how to implement multi-lanuage routes in express.js. i want to use the accept-language header to get the b

相关标签:
5条回答
  • 2020-12-29 07:46

    Middleware recommendation

    The answer by @miro is very good but can be improved as in the following middleware in a separate file (as @ebohlman suggests).

    The middleware

    module.exports = {
      configure: function(app, i18n, config) {
        app.locals.i18n = config;
        i18n.configure(config);
      },
      init: function(req, res, next) {
        var rxLocale = /^\/(\w\w)/i;
        if (rxLocale.test(req.url)){
          var locale = rxLocale.exec(req.url)[1];
          if (req.app.locals.i18n.locales.indexOf(locale) >= 0)
            req.setLocale(locale);
        }
        //else // no need to set the already default
        next();
      },
      url: function(app, url) {
        var locales = app.locals.i18n.locales;
        var urls = [];
        for (var i = 0; i < locales.length; i++)
          urls[i] = '/' + locales[i] + url;
        urls[i] = url;
        return urls;
      }
    };
    

    Also in sample project in github.

    Explanation

    The middleware has three functions. The first is a small helper that configures i18n-node and also saves the settings in app.locals (haven't figured out how to access the settings from i18n-node itself).

    The main one is the second, which takes the locale from the url and sets it in the request object.

    The last one is a helper which, for a given url, returns an array with all possible locales. Eg calling it with '/about' we would get ['/en/about', ..., '/about'].

    How to use

    In app.js:

    // include
    var i18n = require('i18n');
    var services = require('./services');
    
    // configure
    services.i18nUrls.configure(app, i18n, {
      locales: ['el', 'en'],
      defaultLocale: 'el'
    });
    
    // add middleware after static
    app.use(services.i18nUrls.init);
    
    // router
    app.use(services.i18nUrls.url(app, '/'), routes);
    

    Github link

    The locale can be accessed from eg any controller with i18n-node's req.getLocale().

    RFC

    What @josh3736 recommends is surely compliant with RFC etc. Nevertheless, this is a quite common requirement for many i18n web sites and apps, and even Google respects same resources localised and served under different urls (can verify this in webmaster tools). What I would recommended though is to have the same alias after the lang code, eg /en/home, /de/home etc.

    0 讨论(0)
  • 2020-12-29 07:46

    Not sure how you plan on organizing or sharing content but you can use regular expressions with express routes and then server up different templates. Something like this:

    app.get(/^\/(startseite|home)$/, function(req, res){
    
    });
    

    One thing that I did was to organize my content with subdomains and then use middleware to grab the content out of the database based splitting the url, but they all shared the same routes and templates.

    0 讨论(0)
  • 2020-12-29 07:50

    I'd just serve up the content in the detected language directly.

    For example, example.com/home serves up the home page in the best available Accept-Language (possibly overridden by cookie if you provide a language selection option on the site itself).

    You'd want to make sure that your response's Vary: header includes Accept-Language.

    IMO, including language codes in the URI is an ugly hack. The RFC's intent is that a single resource (your home page) is universally represented by a single URI. The entity returned for a URI can vary based on other information, such as language preferences.

    Consider what happens when a German-speaking user copies a URL and sends it to an English-speaking user. That recipient would prefer to see your site in English, but because he has received a link that points to example.com/de/startseite, he goes straight to the German version.

    Obviously, this isn't ideal for full internationalization of what the user sees in the address bar (since home is English), but it's more in line with the RFCs' intent, and I'd argue it works better for users, especially as links get spread around email/social/whatever.

    0 讨论(0)
  • 2020-12-29 07:55

    Write a middleware function that parses any "Accept-Language" headers and sets a request-level local variable to an appropriate code (like a two-letter language code) with a default value (like "en") if there are no such headers or you don't support any language listed. In your routes, retrieve the local and tack it on to any template file names, and branch on it if there's any language-dependent processing other than template selection.

    0 讨论(0)
  • 2020-12-29 07:59

    i have done the following: install i18n-node modul and register in the express js. here is code.

    var express = require('express')
      , routes = require('./routes')
      , http = require('http')
      , i18n = require("i18n");
    
      var app = express();
    
    i18n.configure({
        // setup some locales - other locales default to en silently
        locales:['de', 'en'],
        // disable locale file updates
        updateFiles: false
    });
    
    app.configure(function(){
      ...
      app.use(i18n.init);
      ...
    });
    // register helpers for use in templates
    app.locals({
      __i: i18n.__,
      __n: i18n.__n
    });
    

    after this set the following to get all request

    // invoked before each action
    app.all('*', function(req, res, next) {
        // set locale
        var rxLocal = /^\/(de|en)/i;
        if(rxLocal.test(req.url)){
            var arr = rxLocal.exec(req.url);
            var local=arr[1];
            i18n.setLocale(local);
        } else {
            i18n.setLocale('de');
        }
        // add extra logic
        next();
    });
    
    app.get(/\/(de|en)\/login/i, routes.login);
    

    maybe this help.

    0 讨论(0)
提交回复
热议问题