Forum Moderators: phranque

Message Too Old, No Replies

RewriteRule + 301 redirects are clashing

         

pinkshiro

7:39 pm on Mar 10, 2011 (gmt 0)

10+ Year Member



Hi all...

I have the following in my .htaccess file:

Options +FollowSymLinks

RewriteEngine on

RewriteRule products/?$ new-products.php [L]

Which successfully displays the content in new-products.php when I use the URL www.mydomain.com/products.

If anyone types in www.mydomain.com/new-products.php, I want the website to 301 redirect them to www.mydomain.com/products - as this is the new URL for that page.

My .htaccess causes a redirection issue which will never resolve when I add:

Redirect 301 /new-products.php [mydomain.com...]

What's the best way to achieve what I am attempting to do here?

Thanks for your help in advance.

jdMorgan

8:34 pm on Mar 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You should not accept both "www.mydomain.com/products" and "www.mydomain.com/products/" as valid URLs -- Pick one as the "correct" URL, link only to that URL from your own pages, and redirect the other one to that URL.

Similarly, you should not accept requests for both "www.example.com" and "example.com" if your server resolves both of these to your site.

If you don't take these steps, you are allowing (and paying for) three search-ranking "competitors" to your own site -- and that "competitor" is your very own site!

Lastly, do not mix the use of the "Redirect" or "RedirectMatch" and "RewriteRule" directives. On some sites (such as yours), this immediately causes problems. On others, the problem only shows up after a server upgrade or a change to a new host. In either case, using RewriteRule for all redirects and rewrites, and putting all external redirect rules ahead of internal rewrite rules will prevent these problems.

For your specific problem, no robust and "portable" solution exists using the Redirect and/or RedirectMatch directives; a RewriteRule is required because the solution requires a RewriteCond to differentiate direct client requests from internally-rewritten requests to both avoid the loop you encountered and allow your internal rewrite to work.

Fixing all of these shortcomings results in the following code:

Options +FollowSymLinks
#
RewriteEngine on
#
# Externally redirect only direct client requests for script filepath to new extensionless "products" URL
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /new-products\.php([?#][^\ ]*)?\ HTTP/
RewriteRule ^new-products\.php$ http://www.example.com/products [R=301,L]
#
# Externally redirect all requests for non-canonical products-page
# URL (with trailing slash) to canonical URL (no trailing slash)
RewriteRule ^products/$ http://www.example.com/products [R=301,L]
#
# Externally redirect all requests for non-blank non-canonical hostnames to canonical hostname.
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#
# Internally rewrite requests for canonical extensionless "products" URL-path to products script filepath.
RewriteRule ^products$ /new-products.php [L]

Adjust the first, second, and fourth rules as needed, depending on your choice for the canonical "products" page URL.

Adjust the first three rules as needed, depending on your choice (www or non-www) for the canonical hostname.

These rules in this specific order will fix the problems described above using only a single client redirect to fix all the problems with any client request.

Jim

g1smd

8:44 pm on Mar 17, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



To add further, the order of the rules is ultra important.

The above order prevents any request resulting in an unwanted multiple step redirection chain.