Redirect according to browser language: mod rewrite and HTTP_ACCEPT_LANGUAGE
.htaccess, apache, mod-rewrite Leave commentI wanted to redirect users to the main page of the website according to his/her browser default language setting.
This setting is sent by the browser at every request to the server as ‘Accept-Language’ header and can look like this “pl,en-us;q=0.7,en;q=0.3″. You can check it with Live HTTP Headers Add-on for Firefox and read more about this header at W3C HTTP specification.
In PHP I could do it by checking the value of $_SERVER['HTTP_ACCEPT_LANGUAGE'] and issuing the header(”Location: /LANG/foo.php”,TRUE,301); command.
But I didn’t want to use PHP and did want to do it with .htaccess and mod rewrite. The first thought was to use RewriteCond %{HTTP_ACCEPT_LANGUAGE} as the analogy to RewriteCond %{HTTP_USER_AGENT} or RewriteCond %{HTTP_REFERER}. Unfortunately RewriteCond %{HTTP_ACCEPT_LANGUAGE} does not work! This variable is not present.
What is the solution? Looking more closely at the documentation at http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html we have:
%{HTTP:header}, where header can be any HTTP MIME-header name, can always be used to obtain the value of a header sent in the HTTP request.
Which means we can obtain the value of default language setting of the browser by using RewriteCond %{HTTP:Accept-Language}. This is the simple solution, difficult to find on the web.
So if we have a website with three languages: English, German and Spanish and we want English to be the default we would use for example this in .htaccess:
#The 'Accept-Language' header starts with 'de'
#and the test is case-insensitive ([NC])
RewriteCond %{HTTP:Accept-Language} ^de [NC]
#Redirect user to /de/hauptseite address
#sending 301 (Moved Permanently) HTTP status code
RewriteRule ^$ /de/hauptseite [L,R=301]
RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteRule ^$ /es/pagina-primera [L,R=301]
#For every other language (including English :)) use English
RewriteRule ^$ /en/main-page [L,R=301]
If you need to be more specific (eg. redirect accordingly to US or Great Britain English (en-us and en-gb)) you would not check only the first two signs of ‘Accept-Language’ header but you would need to prepare a little bit more complicated regular expression (some language settings are only two signs, some five signs).
I also thought about possibility of changing redirection addresses from within the CMS system (so that the admin can change main-page, hauptseite or pagina-primera to whatever he/she wishes). The best way would be to save this information in another file (e.g. lang-redirects.conf) and include it within .htaccess. Unfortunately config files inclusion is not possible in .htaccess scope. Another solution I thought about was using mapping-function but it doesn’t work, either.
So the only we can do is to edit .htaccess itself. If anyone knows a nicer solution please share it with us.
Do you know any other tips & tricks regarding .htaccess and/or mod rewrite? We are waiting.
May 25th, 2010 at 2:53 pm
Thanks for the post…
I tested the headers with send http tool and its working fine.
May 25th, 2010 at 2:56 pm
sorry, the link to the tool is:
http://soft-net.net/SendHTTPTool.aspx
December 2nd, 2010 at 7:51 am
Hey,
Cheers, this is exactly what i was looking for but for me it needs some modding for simplicity. That is to say: given that i have a site with 11 languages (and it is still to grow) and in each language the home page is:
[LANG]/home.html
i’d like to do something similar:
#if you have requested http://www.dierre.com/
RewriteCond %{REQUEST_URI} ^/$
RewriteRule (.*) /{HTTP:Accept-Language}/home.html [R=301,L]
Obviously, the “Accept-Language” string contains stuff like “en-us,en;q=0.5″ so the rule above would NOT work like this.
Do you know a way of how to extract only the first 2 chars and use that for the rewrite part?
Adam
February 19th, 2011 at 12:35 pm
Nice one! Thanks!
March 8th, 2011 at 2:57 pm
Doesn’t this code make it impossible for an english browser to view the spanish site?
In my case, I want to redirect the user only when they visit the root page (www.domain.com), to the correct language version (e.g. http://www.domain.com/en/). If they visit any non-root page (e.g. “www.domain.com/es/page1.html”) then I do not want to redirect them anywhere.
July 6th, 2011 at 5:11 pm
I’ve run into a problem with this code. If an non-English speaker wants to visit the English site, it won’t let them see it. It redirects them back to their native language. Any idea how to change this?
August 11th, 2011 at 11:04 pm
Thanks.
Worked fine!
August 11th, 2011 at 11:22 pm
I found the fix, btw. You simply cannot put your main landing homepage/files in the root. They should be in a subdirectory such as /en/ or /es/
October 26th, 2011 at 3:01 am
Thanks for your good job…
I tested the headers with my site: remove fake windows restore virus ,the htacess RewriteRule worked fine!
December 11th, 2011 at 2:53 am
Working! Thanks!
August 16th, 2012 at 5:06 pm
Nice idea, but why exactly are you using permamnet redirects?!
August 28th, 2012 at 11:59 am
“Nice idea, but why exactly are you using permamnet redirects?!”
I would be interested to that reason too.