1

I'm struggling with a .htaccess mod_rewrite challenge. Help is appreciated.

I want the following 301 redirects to work:

  1. mysite.com > https://newsite.com/subdirectory/
  2. mysite.com/old_page_1/ > https://newsite.com/subdirectory/new_page_1/
  3. mysite.com/old_page_2/ > https://newsite.com/subdirectory/new_page_2/
  4. mysite.com/old_page_3/ > https://newsite.com/subdirectory/new_page_3/
  5. mysite.com/anything_else > https://newsite.com/anything_else

I'm struggling with the order, or something. Here's my code:

<IfModule mod_rewrite.c>

    RewriteEngine On

    RewriteRule ^/?old_page_1/? https://newsite.com/subdirectory/new_page_1/ [R=301,L]
    RewriteRule ^/?old_page_2/? https://newsite.com/subdirectory/new_page_2/ [R=301,L]
    RewriteRule ^/?old_page_3/? https://newsite.com/subdirectory/new_page_3/ [R=301,L]
    RewriteRule ^/? https://newsite.com/subdirectory/ [R=301,L]
    
    RewriteCond %{HTTP_HOST} ^(www\.)?mysite\.com$
    RewriteRule ^(.*)$ https://newsite.com/$1 [R=301,L]
    
</IfModule>

The first 4 rewrites work, but then the anything_else part is broken by the 4th rewrite.

PhilSmully
  • 13
  • 3

1 Answers1

0
RewriteRule ^/? https://newsite.com/subdirectory/ [R=301,L]

Because the regex ^/? matches everything. You have no end-of-string anchor, so the above matches an optional / at the start of the URL-path, followed by anything. The same applies to the preceding rules - although that may not be a problem.

Note that in .htaccess, the URL-path that is matched by the RewriteRule pattern never starts with a slash, so the /? prefix can be removed.

There is no need for the <IfModule> wrapper, unless you intend to reuse this same code on multiple servers when mod_rewrite might not be available and you still want the old site to function as is (unlikely I would think).

RewriteCond %{HTTP_HOST} ^(www\.)?mysite\.com$
RewriteRule ^(.*)$ https://newsite.com/$1 [R=301,L]

You are checking the requested Host in your last rule, but not in the preceding rules? Are the old and new "domains" pointing to the same place or different servers? This may not be significant if the old URLs don't exist at the new site, although you are 301 (permanently) redirecting the document root?

Note, you should first test with 302 (temporary) redirects and only change to 301 when you are sure it's working OK. 301s are cached persistently by the browser - including any erroneous redirects.

Try the following instead:

RewriteEngine On

RewriteRule ^old_page_1/?$ https://newsite.com/subdirectory/new_page_1/ [R=302,L]
RewriteRule ^old_page_2/?$ https://newsite.com/subdirectory/new_page_2/ [R=302,L]
RewriteRule ^old_page_3/?$ https://newsite.com/subdirectory/new_page_3/ [R=302,L]

RewriteCond %{HTTP_HOST} ^(www\.)?mysite\.com
RewriteRule ^$ https://newsite.com/subdirectory/ [R=302,L]

RewriteCond %{HTTP_HOST} ^(www\.)?mysite\.com
RewriteRule (.*) https://newsite.com/$1 [R=302,L]

Note that I removed the trailing $ (end-of-string anchor) on the CondPattern that checks against the Host header, so as to catch FQDN that end in a dot.

You will need to clear your browser cache before testing.

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • 1
    Thanks @MrWhite, yours looks good. I figured it out on my own, fixed the regex like how you suggested, then did it in this order: 1) rewrite root, 2) rewrite single pages 3) rewrite anything else. – PhilSmully Jun 17 '20 at 20:53
  • And I found this amazing tool for testing: https://htaccess.madewithlove.be/ - no need empty caches :) – PhilSmully Jun 17 '20 at 21:06
  • Glad you got it sorted. Providing you used the end-of-string anchor (`$`) to make the regex more specific then it doesn't really matter in which order you do #1 and #2. – MrWhite Jun 17 '20 at 23:00