Search code examples
apache.htaccesshttp-redirectmod-rewrite

RedirectMatch overrides Redirect in .htaccess


In my .htaccess file I have rules for redirection.

Redirect 301 /abc/ newdomain.example/abc-new/ 

Redirect 301 /def/ newdomain.example/def-new/

Redirect 301 /ghi/ newdomain.example/ghi-new/

RedirectMatch 301 ^/ newdomain.example

My expectations are:

  1. when somebody types olddomain.example/abc is redirected to newdomain.example/abc-new/, olddomain.example/def is redirected to newdomain.example/def-new/.

  2. when somebody types for example olddomain.example/xyz is redirected to newdomain.example

In example above all pages like olddomain.example/abc olddomain.example/def are redirected to newdomain.example

When line with RedirectMatch is removed redirctions works.

I was expecting that according to documentation rules in file are analyzed from top to bottom and when something matches it is picked up. Here it looks like RedirectMatch overrides the rules above.


Solution

  • There is no need to use RedirectMatch in this case. Redirect rules are all "starts with" rules. So you can simplify that to:

    Redirect 301 /abc https://newdomain.example/abc-new 
    Redirect 301 /def https://newdomain.example/def-new
    Redirect 301 /ghi https://newdomain.example/ghi-new
    Redirect 301 / https://newdomain.example/
    

    I tested this on my local server:

    $ curl -s --head https://olddomain.example/foo| grep Location
    Location: https://newdomain.example/
    $ curl -s --head https://olddomain.example | grep Location
    Location: https://newdomain.example/
    $ curl -s --head https://olddomain.example/ | grep Location
    Location: https://newdomain.example/
    $ curl -s --head https://olddomain.example/abc | grep Location
    Location: https://newdomain.example/abc-new
    $ curl -s --head https://olddomain.example/abc/ | grep Location
    Location: https://newdomain.example/abc-new/
    $ curl -s --head https://olddomain.example/abc/path | grep Location
    Location: https://newdomain.example/abc-new/path
    $ curl -s --head https://olddomain.example/xyz | grep Location
    Location: https://newdomain.example/xyz
    

    If you really want to redirect everything else to the home page (not recommended), you can use the following:

    Redirect 301 /abc https://newdomain.example/abc-new 
    Redirect 301 /def https://newdomain.example/def-new
    Redirect 301 /ghi https://newdomain.example/ghi-new
    RedirectMatch 301 /.* https://newdomain.example/
    

    Also tested on my local server:

    $ curl -s --head https://olddomain.example | grep Location
    Location: https://newdomain.example/
    $ curl -s --head https://olddomain.example/ | grep Location
    Location: https://newdomain.example/
    $ curl -s --head https://olddomain.example/abc | grep Location
    Location: https://newdomain.example/abc-new
    $ curl -s --head https://olddomain.example/abc/ | grep Location
    Location: https://newdomain.example/abc-new/
    $ curl -s --head https://olddomain.example/abc/path | grep Location
    Location: https://newdomain.example/abc-new/path
    $ curl -s --head https://olddomain.example/xyz | grep Location
    Location: https://newdomain.example/