How do I redirect just my home page and keep rest of the URLs as it is? - apache

I need to redirect some URLs as they are pointing to same page. For example:
https://www.example.com/home
https://www.example.com/Home
https://www.example.com/index.php
These all URLs need to refirect to:
https://www.example.com/
So I am using this in .htaccess file it is working fine :
Redirect 301 /home https://www.example.com/
But the issue is when I try to access the URL like this:
https://www.example.com/home/sub
It redirects to resulting in 404:
https://www.example.com//sub
I need this URL to work as it is instead of 404 or any redirect:
https://www.example.com/home/sub

Redirect 301 /home https://www.example.com/
Because the mod_alias Redirect directive is prefix-matching and everything after the match is copied onto the end of the target URL. So, when you request /home/sub, /sub is copied on to https://www.example.com/, resulting in https://www.example.com//sub.
I imagine you also have mod_rewrite directives. You should avoid mixing redirects from both modules, so try the following instead using mod_rewrite at the top of the root .htaccess file:
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(home|index\.php)$ / [R=301,L]
The condition that checks against the REDIRECT_STATUS environment variable ensures that only direct requests are processed, as opposed to internally rewritten requests which will result from having a front-controller pattern (which I assume you have later in the file).
You will need to clear the browser cache since the erroneous 301 (permanent) redirect will have been cached by the browser. Test with 302s to avoid potential caching issues.
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirect
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule

Related

.htaccess redirect not redirecting

I am trying to Redirect pages to new location on the same website using .htaccess
the physical file name is displayitems.php but there is a rule in .htaccess
RewriteRule ^buy-online-(.*) ./displayitems.php?url=$1
which is to handle the user friends URLs and works well.
Now i want to redirects these user friendly urls to new location which is on the same website for eg.
redirect https://example.com/buy-online-alhabib-rings4-sku-1658906163 https://example.com/products/jewelry/buy-online-alhabib-rings4-sku-1658906163 [R=301]
redirect https://example.com/buy-online-alhabib-rings3-sku-1658906162 https://example.com/products/jewelry/buy-online-alhabib-rings3-sku-1658906162 [R=301]
redirect https://example.com/buy-online-alhabib-rings2-sku-1658906161 https://example.com/products/jewelry/buy-online-alhabib-rings2-sku-1658906161 [R=301]
redirect https://example.com/buy-online-alhabib-rings1-sku-1658906160 https://example.com/products/jewelry/buy-online-alhabib-rings1-sku-1658906160 [R=301]
these user friendly url doesn't have any extensions like ".php" ".htm" etc
but nothing happening.
I have added this code in php file to check if url doesn't contain \products\ than redirect it to new location with the same name, for testing i just redirect it with 302 once all tested i will change it to 301
if (strpos($_SERVER['REQUEST_URI'], "/products/") === false) { $NewAddress = strtolower("Location:". $ini['website_address_https'] . "products/".$Product['categoriesname']."/".$Product['BrandName'].$_SERVER['REQUEST_URI']); header("$NewAddress",TRUE,302); }
redirect https://example.com/buy-online-alhabib-rings4-sku-1658906163 https://example.com/products/jewelry/buy-online-alhabib-rings4-sku-1658906163 [R=301]
There are 3 main issues here:
The mod_alias Redirect directive takes a root-relative URL-path (starting with a slash) as the source URL, not an absolute URL. So the above will never match.
You have mixed syntax with mod_rewrite. [R=301] is a RewriteRule (mod_rewrite) flags argument and has nothing to do with the mod_alias Redirect directive. Redirect takes the HTTP status code as an optional second argument. eg. Redirect 301 /buy-online-alhabib-rings4-sku-1658906163 ...
Since you are using mod_rewrite (ie. RewriteRule) for your internal rewrite, you should use mod_rewrite for external redirects as well to avoid potential conflicts. These redirects then need to go before your internal rewrite.
Additionally,
In the 4 redirects you have posted it looks like you are simply injecting /products/jewelry at the start of the URL-path. This does not need 4 separate rules, providing you are wanting to redirect all URLs that following this particular format.
Try the following instead:
RewriteEngine On
# Inject (redirect) "/product/jewelry" at the start of the URL-path
RewriteRule ^buy-online-alhabib-rings\d-sku-\d+$ /products/jewelry/$0 [R=301,L]
# Internal rewrite
RewriteRule ^buy-online-(.*) displayitems.php?url=$1 [L]
The $0 backreference in the first rule contains the entire URL-path that is matched by the RewriteRule pattern.
Note that I also removed ./ from the start of the substitution string in the last rule. This is unnecessary here.

How add path to url if the url does not contain substring

I need to redirect all requests from
https://example.com/* to https://example.com/test/* if the URL does not contain the test substring.
So far I have these rewrite rules
RewriteBase /
RewriteCond %{THE_REQUEST} !^/test
RewriteRule ^/?$ /test/$1 [R=301,L] # if the url does not contain test, redirect to url with test
RewriteCond %{THE_REQUEST}% test
RewriteRule ^test?(.*)$ /$1 [L] # mask the fact that the url is not https://example.com/ and instead is https://example.com/test but apache serve the website like if it was on root
If I access https://example.com it redirects to https://example.com/test but gives infinite loop because of the second rule.
How can I combine it, so request to https://example.com/test* do not get redirected but those request at https://example.com/* do without having to change www root directory and so it will work for all URLs.
UPDATE:
The test should be in url (for user experience), but the apache should route like if it was not in url and instead the request came to root url, so application routing is preserved internally without having to change the app itself.
Ah, Ok. However, you should be linking to the /test URLs within your app (so you do still need to "change the app", despite your last comment), otherwise /test isn't actually in the URLs that users and search engines see on the page (they will be redirected) and your users will experience an external redirect every time they click one of your links (bad for SEO and user experience).
The "redirect" implemented in .htaccess to prefix "old" URLs with /test is just for SEO - as with any "old" to "new" URL change. (It should not be required for your app to function - with /test in the URL-path - since your internal URLs should already include /test.)
Try it like this instead:
RewriteEngine On
# Insert "/test" at the start of the URL-path if absent in "direct" requests
RewriteRule %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^test/ /test/$1 [R=301,L]
# Rewrite "/test" URLs back to root
RewriteRule ^test(?:$|/(.*)) /$1 [L]
The REDIRECT_STATUS environment variable is used to prevent a redirect loop. This is empty on the initial request from the client and set to the HTTP response status after the rewrite (below).
Test first with 302 (temporary) redirects and only change to 301 (permanent) when you are sure this is working as intended.
You will need to clear your browser cache before testing.

Redirect all pages from old domain to new specific URL without trailing slash content

I've got an old domain, let's say oldomain.com where I need to redirect all traffic to a specific URL, newdomain.com/path
While redirects from oldomain.com go perfectly, anything with content after the trailing slash will be copied over in the newdomain url structure causing 404's.
For example visiting: oldomain.com/somepage will result in newdomain.com/pathsomepage
What I'm looking for are some rewrite rules that will redirect any and all traffic from oldomain.com to newdomain.com/path without changing the specific "newdomain.com/path" URL.
I'm currently using the rules bellow which leads to the result above:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^oldomain.com
RewriteRule ^(.*) https://newdomain.com/path [P]
PS: the redirect is going to a Magento store.
You are trying to reverse-proxy in your directives (the P flag in the rewrite), but since you are describing a redirect... In the old virtualhost you just need to add a simple Redirect directive like this:
Redirect / https://newdomain.example.com/
This will Redirect all requests no matter how they are made to the new domain. Example GET /something will be redirected to https://newdomain.example.com/something
If you want the target to be a fixed destination like https://newdomain.example.com/path no matter what, use RedirectMatch instead:
RedirectMatch ^ https://newdomain.example.com/path

redirect exact url to another url

There are a bazillion examples online of doing redirects via apache's htaccess, but I can't find any example of redirecting a full URL match to another full URL.
For instance, I have an existing website at
https://example.com
How do I redirect some specific URLs for that domain to a different one:
https://example.com/login --> https://my.example.com/login
https://example.com/register --> https://my.example.com/register
For every other every other path on example.com I need to remain untouched so my site still works fine (i.e. /blog shouldn't redirect somewhere else).
You can use the following :
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteRule ^(login|register)/?$ http://my.example.com/$1 [L,R]
This will redirect example.com/login or example.com/register to http://my.example.com/
You can alternatively accomplish this using the RedirectMatch directive (if the newurl is on a diffrent webserver) :
RedirectMatch ^/(login|register)/?$ http://my.example.com/$1

301 redirect, conflicting with RewriteRule

We did some maintenance today, and moved our web forums from /forums into the root folder of the domain.
We put in a redirect 301 in a .htaccess file:
Redirect 301 /forums/ http://www.ourforums.com/
However, we used to have some links that contained duplicate /forums folders. I.e. www.ourforums.com/forums/forums/forum.1
Obviously the redirect from above now leads to /forum.1, which odes not exist. I would like the old link to actually point to www.ourforums.com/boards/forum.1. I attempted to use something like:
RewriteRule ^/forums/forums http://www.ourforums.com/boards/ [NC,R=301,L]
Regardless of what I tried though, the Redirect seems to supersede any RewriteRules I put in the same file, regardless of whether I place them before the Redirect.
Is there any way I can somehow ensure the RewriteRule is handled before the Redirect?
This is because mod_alias (the Redirect directive) and mod_rewrite (the RewriteRule directive) is conflicting with each other in your case. Both of them play their part in the URL-file-mapping processing pipeline, where URI's get processed, rewritten, flagged, and eventually mapped to a resource and a response. You have a Redirect rule which is getting applied and the response is being flagged as a redirect. The thing about the Redirect directive is that it connects 2 path nodes together, meaning:
/forums/
is connected to
http://www.ourforums.com/
So anything below the /forums folder ends up getting redirected as well. This is why it's catching ^/forums/forums.
You can either stick to just mod_rewrite or use a RedirectMatch that excludes /forums/forums:
RewriteRule ^/forums/forums(.*)$ http://www.ourforums.com/boards$1 [NC,R=301,L]
RewriteRule ^/forums/(.*)$ http://www.ourforums.com/$1 [NC,R=301,L]
or
RedirectMatch 301 ^/forums/(?!forums)(.*)$ http://www.ourforums.com/$1
Manually adding redirect statements like so seems to do the trick for me:
Redirect /forums/forums/forum.1 http://www.ourforums.com/boards/forum.1
I had a somewhat similar problem. I was trying to add redirects from cpanel while I already had some rewrite rules written in my .htaccess file. The error I got was "No maching tag for " What I ultimately did was that kept a copy of my existing rules and cleaned the .htaccess. Then went and added all the redirects that I needed from cpanel, and then at the end put back my own rewrite rules in the end of the file. That worked for me