htacces rewrite tld without changing subdomain or dirs - apache

I am trying to rewrite the following url:
the subdomain should match any subdomain. same for the TLD.
both: http://car.example.com/ and http://cat.example.co.uk should be rewritten
http://subdomain.example.com/some/dir
to
http://subdomain.example.nl/some/dir
and
http://example.com/some/dir
to
http://exampkle.nl/some/dir
(also with www. adress)
but my knowledge of htaccess and rewrite rules in general aren't good enough for this :(
I hope one of you knows the solution.
ps. I did try a search ;)

The challenge comes with having to detect and account for four different possible domain patterns:
example.com → example.nl
example.co.uk → example.nl
sub.example.com → sub.example.nl
sub.example.co.uk → sub.example.nl
So, what this ruleset does is checks that the TLD is not .nl (preventing a loop from occurring), then pulls the subdomain, www or not, off the front (read as "capture anything other than a dot followed by a dot, optional), followed by the base domain, followed by a dot. We don't have to match the entire URL, since we aren't keeping the TLD.
RewriteEngine On
RewriteCond %{HTTP_HOST} !example\.nl$
RewriteCond %{HTTP_HOST} ^([^.]+\.)?example\.
RewriteRule ^ http://%1example.nl%{REQUEST_URI} [NC,L,R=301]
The RewriteRule's ^ matches any URL, then inserts the contents of the first set of parens in the preceding RewriteCond (the subdomain) with %1, and completes the rewriting by appending the requested path and flags to ignore case, make this the last rule, and redirect with a search-engine-friendly 301, ensuring the rewritten URL appears in the user's browser. Any query string (text appearing after a ? in the URL) is automatically included by default.

Try this:
EDIT: See changes to subdomain, using %1 to capture from RewriteCond
RewriteEngine On
# Check if the hostname requested is subdomain.example.com or empty
# Now we attempt to capture the subdomain with (.*)? and reuse with %1
RewriteCond %{HTTP_HOST} ^(.*)?example.com$ [NC]
RewriteCond %{HTTP_HOST} !^$
# Rewrite it as subdomain.example.nl and redirect the browser
RewriteRule ^(.*) http://%1example.nl$1 [L,R,NE,QSA]
# Note: With the above edit for %1, this part should no longer be necessary.
# Then do the same for example.com, with or without the www
RewriteCond %{HTTP_HOST} ^(www\.)?example.com$ [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^(.*) http://www.example.nl$1 [L,R,NE,QSA]

Related

I changed domains and post slug structure at the same time for my WP site. Can I use 1 redirect to do so with htaccess?

I am planning a domain change from example1.com to example2.com. To add a twist to it, I also want to change my permalinks at the same time. My current permalinks for posts have the date and I want to remove it.
I'm a bit hesitant to test and lose SEO so I was hoping someone could confirm this would work before.
Here is what I was thinking:
after changing domains I use this code in my htaccess
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example1.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example1.com [NC]
RewriteRule ^\d{4}/\d{2}/(.*) https://example2.com/$1 [R=301,L]
then I found this rule to change dates:
RewriteRule ^[0-9]{4}/[0-9]{2}/(.*)$ https://example2.com/$1
I saw this one as well:
RewriteRule ^/(\d*)/(\d*)/([A-Za-z0-9-]*)$ https://example2.com/$4
I'm not sure what these rules specifically mean but I THINK I should be able to combine them like this?
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example1.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example1.com [NC]
RewriteRule ^[0-9]{4}/[0-9]{2}/(.*)$ http://example2.com/$1 [L,R=301,NC]
It doesn't seem quite right.
Or would simply changing the permalink structure in WordPress affect the change so that
https://www.example1.com/2019/01/how-to-write-about-cars/
redirects to
https://www.example2.com/how-to-write-about-cars/
UPDATE
Using MrWhite's answer below. I added this code:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example1.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example1.com [NC]
RewriteRule ^/(\d*)/(\d*)/([A-Za-z0-9-]*)$ https://example2.com/$4
This is working now in the case of
https://www.example1.com/2019/01/how-to-write-about-cars/
which redirects to
https://www.example2.com/how-to-write-about-cars/
However
https://www.example2.com/2019/01/how-to-write-about-cars/
does NOT redirect to
https://www.example2.com/how-to-write-about-cars/
It just returns a 404. This likely isn’t an issue as nothing should be bookmarked but just in case, is there a way to fix that?
Or would simply changing the permalink structure in WordPress affect the change
I don't believe this would implement the redirect from the old to new URL structure, if that is what you are thinking. (At least not by default.)
RewriteCond %{HTTP_HOST} ^example1.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example1.com [NC]
RewriteRule ^[0-9]{4}/[0-9]{2}/(.*)$ http://example2.com/$1 [L,R=301,NC]
This looks OK. Although if the new URLs at example2.com don't contain the date (ie. /YYYY/MM/ prefix) then there wouldn't seem to be any need to check the requested hostname.
This rule must also go at the top of the .htaccess file, before any of the existing WordPress directives (ie. before the # BEGIN WordPress comment marker).
You should first test with a 302 (temporary) redirect to avoid potential caching issues.
Final Solution
This can, however, be tidied a bit. The following one-liner should be sufficient:
RewriteRule ^\d{4}/\d{2}/(.*) https://example2.com/$1 [R=301,L]
You do not need any of the RewriteCond directives. (Just the RewriteEngine On directive, if it doesn't already appear elsewhere in the .htaccess file.)
Note the https on the target URL. \d (shorthand character class) is the same as [0-9]. The trailing $ on the regex is not required since regex is greedy by default. The NC flag is not required either, since there is nothing case specific in this regex.
Aside: (Don't use this!)
I saw this one as well:
RewriteRule ^/(\d*)/(\d*)/([A-Za-z0-9-]*)$ https://example2.com/$4
This rule, however, is very wrong! Due to the slash prefix on the RewriteRule pattern this will never match in .htaccess and the rule will do nothing. But there are only 3 capturing groups in the regex, so the $4 backreference would always be empty (everything would be redirected to the homepage, which would likely be treated as a soft-404 by search engines).

.htaccess redirecting URL but not content for subdomain

I'm trying to set up a test site but having real trouble getting .htaccess to redirect properly.
I want the contents of www.example.com/test to show when a user types in test.example.com. My rewrite rules allow me to use test.example.com in the address bar, but it's actually showing me the content of the root (www.example.com), not the test subfolder.
I'm not an .htaccess guru by any stretch, but I've been using Stack Overflow for 5 years and this is the first time I've been stumped enough to ask a question! Your collective wisdom is appreciated.
Here's the relevant part of my .htaccess code:
RewriteEngine On
# Rewrite for http cases
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
# Rewrite for no www cases
RewriteCond %{HTTP_HOST} !www\.example\.com [NC]
#redirect for test subdomain
RewriteCond %{HTTP_HOST} !^test\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
# redirect to correct for old subfolder usage
RewriteRule ^oldsubfolder/$ https://www.example.com/ [L,R=301]
I want the contents of www.example.com/test to show when a user types in test.site.com.
I assume you just have one domain and test.site.com should really be test.example.com (which would seem to be consistent with the rest of your question)?
In the code you've posted, there's nothing that really attempts to do this redirect? In the code you've posted, a request for test.example.com would not be redirected - so if it is then you may be seeing a cached response. Clear your browser cache.
You would need something like:
RewriteCond %{HTTP_HOST} ^(?:www\.)?(test)\.example\.com [NC]
RewriteRule (.*) http://www.example.com/%1/$1 [R,L]
The (?:www\.)? part simply catches an optional www subdomain of the subdomain! Depending on how this subdomain was created, both test.example.com and www.test.example.com might be accessible. (Although I suspect your SSL cert probably doesn't allow this anyway?)
%1 is a backreference to the captured group in the CondPattern (ie. test) and $1 is a backreference to the captured RewriteRule pattern. Capturing the subdomain (eg. "test") just avoids repetition, but also allows for more than one subdomain to be handled by the same rule.
This is also a temporary (302) redirect. Change this to a 301 only when you are sure it's working (if that is the intention). 301s are cached by default, so can make testing problematic.
Clear your browser cache before testing.
# Rewrite for no www cases
RewriteCond %{HTTP_HOST} !www\.example\.com [NC]
#redirect for test subdomain
RewriteCond %{HTTP_HOST} !^test\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
The comment in the middle of this block would seem to be misleading (it doesn't "redirect for test subdomain"). The whole block just redirects to www, excluding the test subdomain. The other code then redirects the subdomain.
UPDATE:
I was hoping it would continue to show test.example.com in the address bar
Yes, this is possible. Providing test.example.com and www.example.com point to the same filesystem then you can simply rewrite the request without actually changing the host. For this example, I'll assume test.example.com and www.example.com point to the same document root.
Change the above redirect to the following rewrite:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} ^(?:www\.)?(test)\.example\.com [NC]
RewriteRule (.*) /%1/$1 [L]
The request now stays on test.example.com and will serve content from test.example.com/test (although this is hidden from the user) since test.example.com and www.example.com are really the same thing.
The check against REDIRECT_STATUS ensures we are only processing the intial request and not the rewritten request, thus avoiding a rewrite loop. REDIRECT_STATUS is empty on the initial request and set to 200 after the first successful rewrite.
However, if test.example.com points somewhere entirely different then you'll need to implement a reverse proxy and "proxy" the request to www.example.com in order to "hide" this from the user.

.htaccess 301 redirect all pages on old domain to a single page on new domain

I'm looking to redirect each and every page on the old domain to a single page on the new domain. It should also redirect both the www and non-www versions. Every single request to the domain old.com, whatever it may be, should lead to www.new.com root.
old.com/1.php
www.old.com/2.php
old.com/2.php
old.com/links/index.php
old.com/about-us.html
old.com/?string=1
should all redirect to:
www.new.com/
I'm looking for a .htaccess solution.
You can use RedirectMatch in the old.com vhost
RedirectMatch permanent .* http://www.new.com/
Redirect appends the trailing portion of the matched URI to the redirection URI but with RedirectMatch it's up to you to choose the parts (if any) that you want to transfer using parentheses and $number references.
If the old and new domains must be aliases for the same document root on disk then you'll probably have to use mod_rewrite
RewriteEngine on
RewriteCond %{HTTP_HOST} old\.com$
RewriteRule .* http://www.new.com/ [L,R=301]
This has already been answered, but here's the code altogether containing helpful comments so people have a reference to look back on later should they forget what it does.
Put this in your .htaccess file:
## Each and every page on old domain redirects to single page
## By appending question mark to new domain, query strings are removed
RewriteEngine on
RewriteCond %{HTTP_HOST} old\.com$
RewriteRule .* http://www.new.com/? [L,R=301]
You can also redirect to a sub directory on another domain, as was the case that I needed to do like this:
## Each and every page on old domain redirects to single page
## By appending question mark to new domain, query strings are removed
RewriteEngine on
RewriteCond %{HTTP_HOST} old\.com$
RewriteRule .* http://www.new.com/sub-directory/? [L,R=301]
This will handle all your redirects including query strings. Excuse the formatting, I'm on a phone :)
RewriteCond %{HTTP_HOST} old\.com$ RewriteCond %{QUERY_STRING} .+
RewriteRule (.*) http://www.new.com$1?%{QUERY_STRING} [L,R=301,QSA]
RewriteCond %{HTTP_HOST} old\.com$
RewriteRule (.*) http://www.new.com$1 [L,R=301,QSA]

How to redirect dynamic pages using htaccess

I have moved site from one framework to another and now I would like to redirect important pages (around 20). How to redirect them using apache rewrite? Here are examples:
Old: http://mydomain.com/ba/stream.php?kat=15
New: http://www.mydomain.com/bs/about-us/our-partners
Old: http://mydomain.com/ba/stream.php?kat=29
New: http://www.mydomain.com/bs/catalogues/it-catalogue
Also, after important pages are listed, I'd like to redirect all remaining links in form:
http://mydomain.com/ba/whatever-is-here
to
http://www.mydomain.com/bs/
Following TerryE's suggestion, I'll attach my latest code which is not working :)
RewriteCond %{QUERY_STRING} ^kat=15$
RewriteRule ^stream\.php$ http://www.mydomain.com/bs/about-us/our-partners [R=301,L]
One more note: I use this code to redirect root domain to www subdomain:
RewriteCond %{HTTP_HOST} ^mydomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.mydomain.com/$1 [R=301,L]
I have placed this root to www code below code for specific pages redirection, and when I test http://mydomain.com/ba/stream.php?kat=15 in browser, I am redirected to http://www.mydomain.com/bs/ba/stream.php?kat=15
Adnan,
You need to add the following lines to your DOCROOT/.htaccess. This assumes that you don't have any .htaccess file in your ba subdirectory. (See Tips for debugging .htaccess rewrite for an explanation of why.)
RewriteEngine On
RewriteBase /
#
# Redirect kat 15 to the Partners page
#
RewriteCond %{QUERY_STRING} ^kat=15$
RewriteRule ^ba/stream\.php$ http://www.mydomain.com/bs/about-us/our-partners? [R=301,L]
#
# Redirect all other kat ids to the corresponding bs page
#
RewriteCond %{QUERY_STRING} ^kat=(\d+)$
RewriteRule ^ba/stream\.php$ http://www.mydomain.com/bs/%1? [R=301,L]
Note:
the rule matches against the UPI less the leading path (in this case /)
you need to have the trailing ? on the replacement string to suppress the existing query parameters.
the %n parameters pick up the match variables from the last successful condition match.

Redirect to a .html if from some domain

I have two domains that are pointing to the same directory, but I would like to redirect them (via mod_rewrite in htaccess) to some specific .html when hitting home.
Like:
if (domain == 'firstdomain')
redirect firstdomain.html
else if (domain == 'seconddomain')
redirect seconddomain.html
[..] I would like to redirect them to some specific .html when hitting home.
A language like PHP is better suited for redirecting a single page.
The following code will redirect http://example.com/ to http://example.com/example.html and http://example.org/ to http://example.org/anotherpage.html. http://www.example.com will be unaffected (note the www. part)
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^$ example.html [R]
RewriteCond %{HTTP_HOST} ^example.org$ [NC]
RewriteRule ^$ anotherpage.html [R]
The first line matches the HTTP Host field (a.k.a. 'domain') against example.com case-insensitive (^ marks the beginning of the string, $ marks the end).
If there is a match, the page will be redirected (second line, [R]) to example.html
The same story for the third and fourth lines.