: 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
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?
More posts by @Steve110
2 Comments
Sorted by latest first Latest Oldest Best
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
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]
Terms of Use Create Support ticket Your support tickets Stock Market News! © vmapp.org2024 All Rights reserved.