4

When users request /, I want to redirect them to /en or /de, depending on their preference specified in the HTTP request header Accept-Language.

I guess this is easy with server-side scripting, but I need a .htaccess solution as it has to work for a static site.

What I tried:

Users get their preferred language, but they don’t get redirected.

Users get redirected, but they don’t (necessarily ‡) get their preferred language.

(‡ Neither does it assure that the language has a quality value greater than 0, nor does it find the preferred language in case both languages are specified with different quality values.)

Is there a solution for this?

Whether making content negotiation redirect somehow, or allowing to check/compare quality values in the RewriteCond directive, or something totally different.

unor
  • 246
  • 2
  • 19

2 Answers2

1

Some thoughts:

If you have access to server configuration, there may be a way : the use of the RewriteMap directive in your server config.

You can then send the Accept-Language header to a Perl or whatever script, that will send back the preferred language that you can use in your RewriteRule with a 301.

If you have access to a language like php, you can use a index.php file in "/" that will send out the redirect with function header('Location: /en/static-pages.html'). From php 5.3 there is also the function locale_accept_from_http(), which returns the prefered locale from the header.

But important : you want users to "get their preferred language". Are you sure this technique makes the user get its preferred language? So many people do not set this in their browser preferences. The automatic language selection should (must?) be combined with the remembering of user’s choice, (cookie), and user’s choice should (must?) take precedence over automatic selection.

Zimmi
  • 1,041
  • 7
  • 11
0

Disclaimer: I have not tested this. I used something similar in the past for this type of logic, using mod_alias to set the variables and let mod_rewrite handle the multiple conditions. This gets easier in Apache 2.4 with If statements.

RewriteEngine On
SetEnvIf Request_URI ^/$            toplevel
SetEnvIf Accept-Language 'fr'       lang_french
RewriteCond %{ENV:toplevel}         1
RewriteCond %{ENV:lang_french}      1
RewriteRule ^   /fr [R=302,L]

I should add that this example is using the apache config and not .htaccess. I remember there being some caveats around mod_rewrite in .htaccess, but I never use it due to the latency penalties. Good luck!

Aaron
  • 2,809
  • 2
  • 11
  • 29
  • But this does not take preference into account, or does it? It would still serve French, even if the `Accept-Language` header says `fr;q=0` (where French should not be served at all, as it has no quality value greater than 0). And it would still serve French even if the header says `fr;q=0.7, en;q=0.9` (where English should be served, as it has a higher quality value) – unor Jan 02 '15 at 13:55
  • It does not take that into account. To select the language based on the persons preference would require scripting that may be too complicated for mod_rewrite or mod_alias to handle. I will dig into it a little more. – Aaron Jan 02 '15 at 16:55
  • There is a [Howto-Forge](https://www.howtoforge.com/using-apache2-content-negotiation-to-serve-different-languages) document that shows how to handle languages by priority, but this will require creating different copies of the pages based on language preference rather than a directory structure. – Aaron Jan 02 '15 at 17:02
  • This tutorial is about using mod_negotiation (which I also tried, as stated in my question), and as far as I understand it, it doesn’t offer a way to *redirect* to the language-specific URLs: the preferred language gets selected, but the user stays on the same, initial URL (showing the document in the correct language). -- This is the core of my question: one way allows to select the correct language, but doesn’t redirect; the other way redirects, but doesn’t select the correct language. – unor Jan 03 '15 at 00:49
  • Agreed. I don't see a good way to accomplish this using a redirect and also honor the language preference accurately. If I were stuck using a redirect, I might just throw in a third variable that looks for "language;q=0.[0-9]," but it would not really meet your requirement. – Aaron Jan 03 '15 at 02:06