Redirect based on set cookie - .htaccess

I have a bilingual website.
The user should be automatically redirected to the appropriate subdirectory /en/ and /de/ based on his browser language. I achieve that via .htaccess.
On the website is a language switcher if the user nevertheless wants to switch the language. When the language is switched, there’s a cookie set which contains either the value en or de.
Now I’d like my htaccess to check if there’s a cookie set and if yes: Check the value and redirect to the appropriate folder. If not: Check the browser language and redirect to the appropriate folder.
This is what I have so far but it gives me an error: Too many redirects …
RewriteEngine on
RewriteCond %{HTTP_COOKIE} Test=en; [NC]
RewriteRule ^ http://example.com/en [L,R=301]
RewriteCond %{HTTP_COOKIE} Test=de; [NC]
RewriteRule ^ http://example.com/de [L,R=301]
RewriteCond %{HTTP:Accept-Language} ^de [NC]
RewriteRule ^$ http://example.com/de [L,R=301]
RewriteRule ^$ http://example.com/en [L,R=301]
This is the code that generates the cookie:
if (session_id() == '') {
session_start();
}
$lang = basename ( $_SERVER['REQUEST_URI'] );
setcookie("Test", $lang);

You're not restricting the redirection when the URL has already been redirected once. This is causing the infinite redirection loop.
RewriteCond %{REQUEST_URI} !^/(?:en|de) [NC]
RewriteCond %{HTTP_COOKIE} test=(en|de) [NC]
RewriteRule ^(.*)$ http://example.com/%1/$1 [R=301,L]
RewriteCond %{HTTP:Accept-Language} ^de [NC]
RewriteRule ^$ http://example.com/de [R=301,L]
RewriteRule ^$ http://example.com/en [R=301,L]

Related

301 htaccess redirects with 3 parameters to static urls

Im trying to redirect several urls with 3 parameters to different static urls with .htaccess but nothing working.
1.
http://olddomain.com/index.php?id_category=28&controller=category&id_lang=2
to
https://newdomain.com/page1/
http://olddomain.com/index.php?id_category=30&controller=category&id_lang=2
to
https://newdomain.com/page2/
http://olddomain.com/index.php
to
https://newdomain.com
I tried the below code but http://olddomain.com/index.php not going to https://newdomain.com :
RewriteCond %{HTTP_HOST} ^olddomain.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.olddomain.com [NC]
RewriteRule ^(.*)$ https://newdomain.com/$1 [L,R=301,NC]
RewriteCond %{QUERY_STRING} ^id_category=28&controller=category&id_lang=2$
RewriteRule ^index.php$ https://newdomain.com/page1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^id_category=30&controller=category&id_lang=2$
RewriteRule ^index.php$ https://newdomain.com/page2/? [R=301,L]
You need to have specific longer matches first and then have rules to remove index.php or domain redirect:
RewriteEngine On
# specific redirects with index.php as optional match
RewriteCond %{QUERY_STRING} ^id_category=28&controller=category&id_lang=2$ [NC]
RewriteRule ^(index\.php)?$ https://newdomain.com/page1/? [R=301,L,NC]
RewriteCond %{QUERY_STRING} ^id_category=30&controller=category&id_lang=2$ [NC]
RewriteRule ^(index\.php)?$ https://newdomain.com/page2/? [R=301,L,NC]
# remove index.php and redirect to newdmain
RewriteCond %{HTTP_HOST} ^(?:www\.)?olddomain\.com$ [NC]
RewriteRule ^(?:index\.php/?)?(.*)$ https://newdomain.com/$1 [L,R=301,NC,NE]
Make sure to clear your browser cache before testing this change.
In case you are taking page's id from id_lang= variable then please try following rules. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##Rules to redirect to link: https://newdomain.com/page1/ here.
RewriteCond %{HTTP_HOST} ^(?:www\.)?olddomain\.com$ [NC]
RewriteCond %{THE_REQUEST} \s/index\.php\?id_category=28&controller=category&id_lang=(\d+)\s [NC]
RewriteRule ^ https://newdomain.com/page%1/? [NE,R=301,L]
##Rules to redirect https://newdomain.com/ here.
RewriteCond %{HTTP_HOST} ^(?:www\.)?olddomain\.com$ [NC]
RewriteCond %{THE_REQUEST} \s/index\.php\s [NC]
RewriteRule ^ https://newdomain.com [NE,R=301,L]

How to redirect to folder in .htaccess?

I want to redirect all the languages except the English for example, to another folder. If you are not english and you go to www.webpage.com/work/ you will go to www.webpage.com/xx/work
Now I have this code:
RewriteEngine on
RewriteCond %{HTTP:Accept-Language} (aa|ab|af|am|ar|as|ay|az|ba|be|bg|bh|bi|bn|bo|br|co|cs|cy|da|de|dz|el|en|eo|et|eu|fa|fi|fj|fo|fr|fy|ga|gd|gl|gn|gu|ha|hi|hr|hu|hy|ia|ie|ik|in|is|it|iw|ja|ji|jw|ka|kk|kl|km|kn|ko|ks|ku|ky|la|ln|lo|lt|lv|mg|mi|mk|ml|mn|mo|mr|ms|mt|my|na|ne|nl|no|oc|om|or|pa|pl|ps|pt|qu|rm|rn|ro|ru|rw|sa|sd|sg|sh|si|sk|sl|sm|sn|so|sq|sr|ss|st|su|sv|sw|ta|te|tg|th|ti|tk|tl|tn|to|tr|ts|tt|tw|uk|ur|uz|vi|vo|wo|xh|yo|zh|zu) [NC]
RewriteRule .* www.webpage.com/en/ [R,L]
But I want to redirect from /work/ to /xx/work/
Thanks
You need to use back reference to captured text in RewriteCond using %1:
RewriteEngine on
RewriteCond %{HTTP:Accept-Language} (aa|ab|af|am|ar|as|ay|az|ba|be|bg|bh|bi|bn|bo|br|co|cs|cy|da|de|dz|el|en|eo|et|eu|fa|fi|fj|fo|fr|fy|ga|gd|gl|gn|gu|ha|hi|hr|hu|hy|ia|ie|ik|in|is|it|iw|ja|ji|jw|ka|kk|kl|km|kn|ko|ks|ku|ky|la|ln|lo|lt|lv|mg|mi|mk|ml|mn|mo|mr|ms|mt|my|na|ne|nl|no|oc|om|or|pa|pl|ps|pt|qu|rm|rn|ro|ru|rw|sa|sd|sg|sh|si|sk|sl|sm|sn|so|sq|sr|ss|st|su|sv|sw|ta|te|tg|th|ti|tk|tl|tn|to|tr|ts|tt|tw|uk|ur|uz|vi|vo|wo|xh|yo|zh|zu) [NC]
RewriteRule ^$ /%1/work/ [R,L]
RewriteCond %{HTTP:Accept-Language} (aa|ab|af|am|ar|as|ay|az|ba|be|bg|bh|bi|bn|bo|br|co|cs|cy|da|de|dz|el|en|eo|et|eu|fa|fi|fj|fo|fr|fy|ga|gd|gl|gn|gu|ha|hi|hr|hu|hy|ia|ie|ik|in|is|it|iw|ja|ji|jw|ka|kk|kl|km|kn|ko|ks|ku|ky|la|ln|lo|lt|lv|mg|mi|mk|ml|mn|mo|mr|ms|mt|my|na|ne|nl|no|oc|om|or|pa|pl|ps|pt|qu|rm|rn|ro|ru|rw|sa|sd|sg|sh|si|sk|sl|sm|sn|so|sq|sr|ss|st|su|sv|sw|ta|te|tg|th|ti|tk|tl|tn|to|tr|ts|tt|tw|uk|ur|uz|vi|vo|wo|xh|yo|zh|zu) [NC]
RewriteRule ^((?![a-z]{2}/).+)$ /%1/$1/ [R,L]

htaccess Redirect only if the HTTP referrer does NOT equal something

I have the following rules working to redirect chinese users to the chinese language version of the site:
RewriteCond %{HTTP:Accept-Language} ^zh [NC]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://ch.example.com/$1 [L,R=301]
RewriteCond %{HTTP:Accept-Language} ^zh [NC]
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://ch.example.com/$1 [L,R=301]
This works great.
However, there is a link that is supposed to take them back to the english language version of the site, which is just the normal domain (www.example.com).
But this just redirects them straight back to the chinese site, because it matches the rules. So I need to make it so the above rules are trigger ONLY if the referer is NOT ch.example.com.
I tried something like this:
RewriteCond %{HTTP:Accept-Language} ^zh [NC]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteCond %{HTTP_REFERER} !^http?://ch\.example\.com/ [nc]
RewriteRule ^(.*)$ http://ch.example.com/$1 [L,R=301]
But it doesn't work.
What about when the user views their second page on the English site, it will redirect to Chinese. A better method is to set a cookie and then check it:
For example: http://www.askapache.com/htaccess/htaccess-fresh.html#Set_Cookie_based_Requested_directory

htaccess + redirect users depending on the browser language

I was reading all questions related to this topic and I couldn't find anything.
First, I have this domain: www.example.com
My purpose is to redirect users depending on the language of the browser:
ex: www.example.com => www.example.com/es
www.example.com => www.example.com/en
I followed this rule but here is not the source url:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteCond %{HTTP_REFERER} !^*\.domain\.com.ar/ [NC]
RewriteRule ^$ http://www.example.com/es / [L,R]
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteCond %{HTTP_REFERER} !^*\.domain\.be/ [NC]
RewriteRule ^$ http://www.example.com/en / [L,R]
</IfModule>
In this piece of code, where is establish the destination website?
Here:
RewriteRule ^$ http://www.example.com/es / [L,R]
and here:
RewriteRule ^$ http://www.example.com/en / [L,R]
No idea if that's a typo or if this is what you have in your htaccess file, but this will produce 500 internal server errors because you are giving RewriteRule 4 parameters, when it only wants either 2 or 3.
The other problem is with your %{HTTP_REFERER} regular expression. Apache's probably going to puke here: ^*\.domain\.com.ar/, you probably meant: ^[^/]*\.domain\.com.ar/ or something. So you probably want your rules to look like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteCond %{HTTP_REFERER} !^[^/]*\.domain\.com.ar/ [NC]
RewriteRule ^$ http://www.example.com/es/ [L,R]
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteCond %{HTTP_REFERER} !^[^/]*\.domain\.be/ [NC]
RewriteRule ^$ http://www.example.com/en/ [L,R]
</IfModule>
Of course, you'd be replacing the instances of domain.com.ar and domain.be and www.example.com with the correct hostnames.
Also note: the Accept-Language header is a complicated string of qualifiers. It isn't as simple as an en or es. A spanish webbrowser could contain both an en and es simply because both are supported languages. Determining an exact language to redirect to based on this header isn't really in the scope of mod_rewrite and htaccess.
If you want to check domain and browser language, this is what you could do:
# Check domain (1), browser language (2) and redirect to subdirectory (3)
RewriteCond %{HTTP_HOST} .*example.com [NC]
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteRule ^$ http://%{HTTP_HOST}/en/ [L,R=301]
# ... copy block above for other languages ...
# Fallback for any other language to spanish
RewriteCond %{HTTP_HOST} .*example.com [NC]
RewriteRule ^$ http://%{HTTP_HOST}/es/ [L,R=301]

.htaccess - how to force "www." in a generic way?

This will change domain.example to www.domain.example:
# Force the "www."
RewriteCond %{HTTP_HOST} !^www\.domain\.example$ [NC]
RewriteRule ^(.*)$ `http://www.domain.example/$1` [R=301,L]
How do I replace the "domain" part so that this works on any domain?
I would use this rule:
RewriteEngine On
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
The first condition checks whether the Host value is not empty (in case of HTTP/1.0); the second checks whether the the Host value does not begin with www.; the third checks for HTTPS (%{HTTPS} is either on or off, so %{HTTPS}s is either ons or offs and in case of ons the s is matched). The substitution part of RewriteRule then just merges the information parts to a full URL.
This will do it:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
If you want to redirect all non-www requests to your site to the www version, all you need to do is add the following code to your .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
This won't work with subdomains.
domain.example correctly gets redirected to www.domain.example
but
images.domain.example gets redirected to www.images.domain.example
Instead of checking if the subdomain is "not www", check if there are two dots:
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteCond %{HTTP_HOST} !^(.*)\.(.*)\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ HTTP%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
The following should prefix 'www' to any request that doesn't have one, and redirect the edited request to the new URI.
RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
RewriteCond "%{HTTP_HOST}" "(.*)"
RewriteRule "(.*)" "http://www.%1$1" [R=301,L]
RewriteEngine On
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
This redirects example.com to www.example.com excluding subdomains.
This is an older question, and there are many different ways to do this. The most complete answer, IMHO, is found here: https://gist.github.com/vielhuber/f2c6bdd1ed9024023fe4 . (Pasting and formatting the code here didn't work for me)
this worked like magic for me
RewriteCond %{HTTP_HOST} ^sitename.example [NC]
RewriteRule ^(.*)$ https://www.sitename.example/$1 [L,R=301,NC]

Resources