Forum Moderators: phranque

Message Too Old, No Replies

Redirect based on browser language

         

Philippe2703

3:13 pm on Oct 26, 2010 (gmt 0)

10+ Year Member



I discovered a major problem with my website late last night and can't figure it out. I really need help.

Right now I have a redirect based on language which looks like this:
DirectoryIndex index.html index.php
<IfModule mod_rewrite.c>

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !\.(png|gif|ico|swf|jpe?g|js|css)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php?sef_rewrite=1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} .*\/catalog\/.*
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteRule . index.php?sef_rewrite=1 [L,QSA]

RewriteCond %{HTTP:Accept-Language} (fr) [NC]
RewriteRule ^$ /fr/ [L,R=301]

RewriteCond %{HTTP:Accept-Language} (en) [NC]
RewriteRule ^$ /en/ [L,R=301]

I know there's a way to simplify and not have the 100 languages there but I had it before and wasn't working any better.

Everything redirects correctly but when I use Internet Explorer, for the 2nd language that I have (in this case english), users won't be able to sign-in. If I switch english and french, it'll be the opposite.

In Firefox everything works fine. Any ideas?

jdMorgan

4:44 pm on Oct 26, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Those rules appear to be completely out of order. See [webmasterworld.com...]

The problem may be that your IE browser is not configured to send *any* Accept-Language header, in which case, neither of your rewrites will apply. You need to pick a default language and rewrite to that language's files if no Accept-Language header is sent.

There's also another possibility: The browser may be set up to accept both languages -- See additional notes below.

Taking care of both of the above issues with a few additional minor tweaks, I would suggest:

DirectoryIndex index.html index.php
#
RewriteBase /
#
# Redirect to language-specific subdirectory based on the first language
# code found in the Accept-Language request header sent by the client
RewriteCond %{HTTP:Accept-Language} ^([^\-,;]+[\-,;])*([a-z]{2})([-,;].+)?$ [NC]
RewriteRule ^$ http://www.example.com/%2/ [R=301,L]
#
# Else redirect to default language (Français-Québécoise)
RewriteRule ^$ http://www.example.com/fr/ [R=301,L]
#
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^([^/]*/)*catalog/ index.php?sef_rewrite=1 [QSA,L]
#
RewriteCond %{REQUEST_FILENAME} !\.(png|gif|ico|swf|jpe?g|js|css)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php?sef_rewrite=1 [QSA,L]

There is still a problem here, and one which may require re-thinking your entire approach.

An example a typical "Accept-Language" header may look like this:
"fr-ca;q=0.8,fr-fr;q=0.7,fr;q=0.6,en-us;q=0.5,en;q=0.3"

This says that the Canada dialect of French is preferred most, followed by the France dialect, followed by any other country or regional dialect (e.g. Algeria), followed by U.S. English, and then by any other dialect of English.

Neither your original multi language-rule code nor my single-rule code addresses this priority; If the first-tested language code is found *anywhere* in the Accept-Language header, then that language is selected.

Then there is the 'blank Accept-Language header' problem already discussed.

At an even deeper level, the Accept-Language headers sent by a browser do not necessarily reflect the actual language preferences of the user. The user may have never set these preferences. They may be blank or still set to the factory default. If the user has multiple browsers installed, they may even be set differently. In addition, what about internet cafes and airport and hotel internet-access kiosks? Schools? Libraries? Government and business offices? Any place where the user does not "own" the computer is problematic.

Really, a better approach is to let the user select his/her preferred language using the "world map" or "rows of tiny flags" methods on a bi-lingual or multi-lingual home page.

If you want to continue to try to user client-provided language preferences, I suggest that you redirect all login-page requests to a script which can properly-parse the Accept-Language headers by checking the "preference-weighting factors" of each indicated language, and then generate s proper redirect response.

If the Accept-Language header is blank, you can also look at the browser user-agent string (for example, Mozilla and Safari-based browser (e.g. Safari and Chrome) user-agent strings contain a language- and optional country-code indicating the localized version of the browser which was installed.

But either way, using the "world map" or "tiny flags" method will be needed to address the fact that neither the computer OS nor the browser may actually be configured to reflect the actual user's language preferences.

Also, get rid of the <IfModule> test. All it does is to cause this code to fail silently if mod_rewrite is (or becomes) unavailable, or it wastes CPU time by testing for that module's presence for each and every HTTP request received by your server.

Jim

Philippe2703

12:42 pm on Oct 27, 2010 (gmt 0)

10+ Year Member



Hi Jim,
Thanks for the response. First I tried to remove the <IfModule> test but if I do that, the redirect doesn't work at all. As for the order of the rules I'll try and fix it. I don't know a lot about this, I kind of find codes for what I need in different places and just paste them without really knowing which order to put them in so that's good to know.

I also tried your code suggestion but the same thing happens. The redirect works fine but it still looks like it's not linked properly to my database and I get the same problem that I described earlier.

I have a feeling this may be more of a shopping cart related issue because the redirect itself seems to work fine. I'll probably contact them and hope they can fix it.

Thanks,
Phil

g1smd

12:57 pm on Oct 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



As for the order of the rules I'll try to fix it.

In the code snippet above, the order has been fixed.

Philippe2703

3:26 pm on Oct 27, 2010 (gmt 0)

10+ Year Member



Yeah I noticed that after I posted it. Thanks

jdMorgan

3:45 pm on Oct 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> I kind of find codes for what I need in different places and just paste them without really knowing which order to put them in

Even before you know the correct order, it is more important to know this: Copying and pasting server configuration code from "all over the Web" without fully understanding the code is one of the most dangerous things you can do. You can --if you are lucky-- immediately cause your site to go off line. If you are not so lucky, a subtle flaw or tiny typo in the code can slowly ruin your search engine rankings and put you out of business.

So to be direct at the expense of politeness, all Webmasters would do very to to fully-understand the code they use and the effects it has on server operation and search ranking, or to not use the code at all. I commend our Apache Forum Charter and our Apache Forum Library to you as a first step in the former process.

Jim

Philippe2703

12:19 pm on Oct 28, 2010 (gmt 0)

10+ Year Member



Well I'm not going to paste random codes that I don't know what they do. I'll know what I'm looking for, look up the code to do it and paste it. If it doesn't work right away I take it out and I do all of this at night when there's no one on my site.

g1smd

12:39 pm on Oct 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Your night, is someone else's day. The web is never asleep.

If you do a lot of tinkering, you'll find it a great help to set up a separate test or dev subdomain.

You could even run Apache on your local box, and add a dev.example.com entry in your HOSTS file to point to it.

Make sure that the test site cannot be accessed by anyone or anything else, by password protecting it.