Mobile app version of vmapp.org
Login or Join
Steve110

: Htaccess need automatic redirect + language + SEO urls I am trying to achieve more things: HTTP:// should redirect to HTTPS:// www.example.com should redirect to www.example.com/en/ or /it/ depending

@Steve110

Posted in: #Htaccess #Language #Redirects #Seo

I am trying to achieve more things:

should redirect to example.com should redirect to example.com/en/ or /it/ depending on client language
links should resolve to example.com?lang=en All urls different from index.php? (e.g. example.com/abcd) should all be redirected to index.php


I got working the 1.3.4 by using:

RewriteEngine On

RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ www.example.com/ [R=301,L]

# RewriteCond %{HTTP:Accept-Language} ^en [NC]
# RewriteRule ^$ www.example.com/en/ [L,R=301]
# RewriteCond %{HTTP:Accept-Language} ^it [NC]
# RewriteRule ^$ www.example.com/it/ [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(en|it)/(.*) ?lang= [QSA]
RewriteRule ^([^/]+)$ index.php?op= [L,NS,QSA] index.php


Trying now to achieve point 2. If I remove the comments it ends up in a redirect loop + error

Is there any way?

10.02% popularity Vote Up Vote Down


Login to follow query

More posts by @Steve110

2 Comments

Sorted by latest first Latest Oldest Best

 

@Jamie184

The rewrite loop is actually caused by rules later in your script:

RewriteRule ^(en|it)/(.*) ?lang= [QSA]
RewriteRule ^([^/]+)$ index.php?op= [L,NS,QSA] index.php


Having redirected the user to /en/ (with the Accept-Language rules), the first directive here rewrites the request back to ?lang=en (no URL-path) but the second directive then fails to match (since there is no URL-path), so it's not rewritten to index.php (a URL-path). The URL-rewriting process then starts over and the user gets redirected to /en/ again (since there is no URL-path), etc.

Providing your script can handle an empty op parameter (it should) then you could probably resolve this by simply changing the last RewriteRule pattern from ^([^/]+)$ to ^([^/]*)$ to catch the empty string.

OR, make sure your penultimate RewriteRule always includes a URL-path. For example, change:

RewriteRule ^(en|it)/(.*) ?lang= [QSA]


to

RewriteRule ^(en|it)/(.*) index.php?op=&lang= [QSA,L]


Although that really duplicates what the last directive is doing (hence the addition of the L flag).

OR, include a condition in your language redirect and only redirect when the lang URL parameter is not present. For example:

RewriteCond %{QUERY_STRING} !lang=[a-z]{2}
RewriteCond %{HTTP:Accept-Language} ^(en|it) [NC]
RewriteRule ^$ www.example.com/%1/ [L,R=301]


This also combines the two rules (en and it) into one.

Just to add... whilst this type of language detection is common, it is possibly over simplified and could potentially result in incorrect language detection. It assumes that the languages are specified in order to preference (which they might not be) and ignores the "quality" (q) parameter. (There have been other questions on this very subject, but I can't just find them at the moment.)



Aside, do you need to check both...?

RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{HTTPS} off

10% popularity Vote Up Vote Down


 

@LarsenBagley505

This answer comes from memory. If I'm 100% correct with the syntax, you'll want to replaced your 4 commented out lines of code with:

RewriteCond %{REQUEST_URI} !^/en(.*)$
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteRule ^$ www.example.com/en/ [L,R=301]
RewriteCond %{REQUEST_URI} !^/it(.*)$
RewriteCond %{HTTP:Accept-Language} ^it [NC]
RewriteRule ^$ www.example.com/it/ [L,R=301]


The intent here is to check the request URI (the part that comes after www.example.com) and see that it is anything but the URI you want to redirect to (thereby avoiding a redirect loop). If the request URI matches, then the rule doesn't get processed.

For example:

RewriteCond %{REQUEST_URI} !^/en(.*)$


..checks to see someone didn't type a url that begins with www.example.com/en and if that's the case, then this is checked:

RewriteCond %{HTTP:Accept-Language} ^en [NC]


..which checks that "en" is in the accept-language header. If the header has "en" and the url does NOT begin with www.example.com/en then the user who attempts to go to www.example.com/ will be redirected to www.example.com/en/ via this rule:

RewriteRule ^$ www.example.com/en/ [L,R=301]

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme