66

User requests some page and I want to know (on server side) what is the language in his/her browser. So I could render template with the right messages.

On client side it's easy:

var language = window.navigator.userLanguage || window.navigator.language
Zeeshan Hassan Memon
  • 8,105
  • 4
  • 43
  • 57
Oleg Dats
  • 3,933
  • 9
  • 38
  • 61

5 Answers5

102

You can use req.headers["accept-language"] to get the language/locale the user has set in his browser.

For easier support, you may want to look into a locale module.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • 2
    req.headers["accept-language"] returns : "uk,ru;q=0.8,en-us;q=0.5,en;q=0.3" Selected language is "uk". How to get this language from the list ? – Oleg Dats Aug 07 '12 at 12:15
  • 5
    @OlegDats The locale module will help you parse that, but basically it means is, the user wants the locales (in preference order) uk (UK English), ru (Russian), en-us (US English), en (plain english), the q is a weight factor, higher q means higher preference. – Joachim Isaksson Aug 07 '12 at 12:19
  • 17
    @JoachimIsaksson uk is not uk english, that would be 'en-gb'. Probably uk is Ukranian. The first two letters are always lanuages, not regions. – UpTheCreek Sep 04 '12 at 06:45
42

request.acceptsLanguages will contain a parsed version of request.headers['accept-language'].

See: http://expressjs.com/en/api.html#req.acceptsLanguages

Salvatorelab
  • 11,614
  • 6
  • 53
  • 80
cGuille
  • 530
  • 4
  • 8
  • 2
    In Express 4 you can use `req.acceptedLanguages` as a way to check if the user accepts a single or list of languages. Check it out: http://blog.hubii.com/dev-detecting-header-language-on-express-js/ – midudev Aug 28 '15 at 09:46
33

With Express 4.x, you can use the build in req.acceptsLanguages(lang [, ...]) to check if certain languages are accepted.

var express = require('express');
app.get('/translation', function(request, response) {
    var lang = request.acceptsLanguages('fr', 'es', 'en');
    if (lang) {
        console.log('The first accepted of [fr, es, en] is: ' + lang);
        ...
    } else {
        console.log('None of [fr, es, en] is accepted');
        ...
    }
});

To get the list of all accepted languages, using Express 4.x, you can use the module accepts.

var express = require('express'), accepts = require('accepts');
app.get('/translation', function(request, response) {
    console.log(accepts(request).languages());
    ...
});
Sergio
  • 28,539
  • 11
  • 85
  • 132
jgrocha
  • 2,912
  • 1
  • 28
  • 31
  • 1
    Actually, `req.acceptsLanguages` just does an `apply` using the accepts module under-the-hood, so if you don't pass it any arguments you will get the same list of languages (as an array in order of preference). Be aware that isn't documented behavior though, the Express docs say that the `lang` argument is required. – Inkling Jan 20 '16 at 03:28
5

Middleware to set the request language and use it globally:

// place this middleware before declaring any routes
app.use((req, res, next) => {
    // This reads the accept-language header
    // and returns the language if found or false if not
    const lang = req.acceptsLanguages('bg', 'en')
    
    if (lang) { // if found, attach it as property to the request
        req.lang = lang
    } else { // else set the default language
        req.lang = 'en'
    }

    next()
})

Now you can access 'req.lang'

app.get('/', (req, res) => {
    res.send(`The request language is '${req.lang}'`)
})

Example using translation

const translate = {
    en: {
        helloWorld: "Hello World!"
    },
    bg: {
        helloWorld: "Здравей Свят!"
    }
}
app.get('/hello-world', (req, res) => {
    res.send(translate[req.lang].helloWorld)
})
Nedko Dimitrov
  • 4,350
  • 3
  • 28
  • 30
0

You would need to parse the string in req.headers["accept-language"]. Which will give you a priority list of preferred languages from the client. You can also check req.acceptsLanguages(lang [, ...]) if your language is supported or not.

I would strongly recommend to use express-request-language to do any language matching work, since it could be very difficult to get it right at the first time.

Most of the time, matching a language is not enough. A user might want to change a preferred language. express-request-language help you store a preferred language in a cookie it also gives your server a URL path to change a preferred language.

All above functionality can be done with just a couple of lines of code:

app.use(requestLanguage({
  languages: ['en-US', 'zh-CN'],
  cookie: {
    name: 'language',
    options: { maxAge: 24*3600*1000 },
    url: '/languages/{language}'
  }
}));

In case of no match, the middleware will also match a default language (en-US above).

einstein
  • 13,389
  • 27
  • 80
  • 110