1

File redirects

Redirect 301 /products.php http://example.com/product_123.php

and domain redirects

Redirect 301 / http://www.example.com/

are easy. However, I want to redirect some URLs ignoring all parameters, i.e.

example.com/slug1/slug2/slug3?pagination=1
example.com/slug1/slug2/slug3?ref=2
example.com/slug1/slug2/slug3?day=Monday
example.com/slug1/slug2/slug3?referer=Google 
example.com/slug1/slug2/slug3?referer=Facebook
... etc  

should all redirect to

example.com/slug4
3

That's where you should use a RedirectMatch directive with regex matching instead of the plain Redirect.

Maybe something along the lines of:

 RedirectMatch 301 "/slug1/slug2/slug3(.*)$" "/slug4"
3
  • 1
    RedirectMatch 301 "/slug1/slug2/slug3(.*)$" ... is the same as a "plain Redirect" (ie. Redirect 301 /slug1/slug2/slug3 ...), since Redirect is prefix matching.
    – MrWhite
    Aug 1 '16 at 9:39
  • @w3d Yes but unlike the normal Redirect the above will strip the arguments. - A plain redirect would redirect /slug1/slug2/slug3?pagination=1 to /slug4?pagination=1, by using the regex grouping allows to redirect /slug1/slug2/slug3?pagination=1 to /slug4,
    – HBruijn
    Aug 1 '16 at 10:06
  • 2
    RedirectMatch behaves the same as Redirect with respect to the query string - it's passed through to the target URL unaltered (unless you explicitly include a query string on the target URL). However, to completely remove the query string you would need to use mod_rewrite (as mentioned in my answer). "by using the regex grouping" - The RedirectMatch (and Redirect) directive only matches against the URL-path, which notably excludes the query string, so given the above example URLs, the "regex group" (.*) actually matches nothing (and is therefore superfluous).
    – MrWhite
    Aug 1 '16 at 18:13
3

If you want to simply ignore all parameters, then you can still use a standard Redirect, because it is prefix matching and does not match against the query string anyway. For example:

Redirect 301 /slug1/slug2/slug3 /slug4

The above Redirect would 301-redirect all the URLs in the question (ie. all URLs that start /slug1/slug2/slug3) to /slug4.

However, any query string on the requested URL will also be passed through to the target URL unaltered. So, /slug1/slug2/slug3?ref=2 will be redirected to /slug4?ref=2. If this is undesirable, and you wish to remove the query string entirely*1, then you will need to use mod_rewrite (ie. RewriteRule), rather than mod_alias (ie. Redirect or RedirectMatch, as suggested in the other answer) in order to explicitly remove the query string completely from the target URL. For example:

RewriteEngine On
RewriteRule ^slug1/slug2/slug3$ /slug4? [R=301,L]

The ? on the end of the RewriteRule substitution will result in the query string being removed from the target URL (you could alternatively use the QSD flag on Apache 2.4+). The query string is not matched by the RewriteRule pattern, so there is nothing extra you need to do in this respect, unless you needed to match specific query strings, or only when there is actually a query string (the above will match regardless of whether a query string is present or not).

An additional caveat with switching to a mod_rewrite redirect is that you should ideally change any existing mod_alias redirects to the equivalent mod_rewrite syntax. This is to avoid any potential conflicts since the two modules execute at different times.

*1 Note that you can simply append a ? (ie. an empty query string) on the end of the target URL with the Redirect or RedirectMatch directives. However, the trailing ? is actually included in the redirected URL, as opposed to be being removed entirely, as with a mod_rewrite RewriteRule directive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.