Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rewrite location in nginx depending on the client-browser's language?

How to rewrite location in nginx depending on the client-browser's language?

For example: My browser accept-language is 'uk,ru,en'. When I request location mysite.org nginx must forward to mysite.org/uk

like image 350
RKI Avatar asked Sep 07 '10 10:09

RKI


People also ask

How do I change my URL in nginx?

NGINX Return directive The easiest and cleaner way to rewrite an URL can be done by using the return directive. The return directive must be declared in the server or location context by specifying the URL to be redirected.


Video Answer


2 Answers

You can manage $language_suffix by this setting when you cannot add AcceptLanguageModule module into your system.

rewrite (.*) $1/$http_accept_language 

A more resilient approach would use a map:

map $http_accept_language $lang {         default en;         ~es es;         ~fr fr; }  ...  rewrite (.*) $1/$lang; 
like image 144
Brian Coca Avatar answered Sep 21 '22 20:09

Brian Coca


The downside of using AcceptLanguageModule is you cannot rely on automatic system updates anymore. And with every nginx update (even security one), you have to compile Nginx yourself. The second downside is that module assumes that the accept-language is sorted by quality values already. I rather prefer Lua because it can be installed easily in debian based distros:

apt-get install nginx-extras

My colleague Fillipo made great nginx-http-accept-lang script in Lua. It correctly handles quality values and does redirect user accordingly. I've made small modification to that script. It accepts supported languages as input parameter and returns the most qualified language according to Accept-Language header. With returned value you can do whatever you want. It can be used for rewrites, setting lang cookie ...

I'm only using language determination for root path only (location = /). And user lang cookie has preference over browser. My nginx conf looks like this:

map $cookie_lang $pref_lang {
    default "";
    ~en en;
    ~sk sk;
}

server {
    listen 80 default_server;

    root /usr/share/nginx/html;
    index index.html index.htm;

    # Make site accessible from http://localhost/
    server_name localhost;

    location = / {
        # $lang_sup holds comma separated languages supported by site
        set $lang_sup "en,sk";
        set_by_lua_file $lang /etc/nginx/lang.lua $lang_sup;
        if ($pref_lang) {
            set $lang $pref_lang;
        }
        add_header Set-Cookie lang=$lang;
        rewrite (.*) $scheme://$server_name/$lang$1;
    }

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
   }
}
like image 41
mauron85 Avatar answered Sep 20 '22 20:09

mauron85