1

I checked a lot, for my question. there are some close, but none that would solve my problem.

I need to permanently redirect ALL URLs that end in this:

?mode=list 

AND

?mode=grid 

to without (remove the question mark and what is after it)

Example:

example.com/random-url-here?mode=grid redirect to example.com/random-url-here 

AND

example.com/whatever-url-here?mode=list redirect to example.com/random-url-here 

I tried this:

RewriteEngine on RewriteRule (.*)$^mode=list $1 RewriteRule (.*)$^mode=grid $1 

and this

RewriteEngine on RewriteRule (.*)$^mode=list $1 [L,R=301] RewriteRule (.*)$^mode=grid $1 [L,R=301] 

But it doesn't work. Clearly, I don't understand how this works. Please help.

Thank you

1
  • The answer to your question is in the docs for RewriteRule. It's really better for me to direct you there rather than answer the question directly, because to manage Apache you'll need to read that whole page many times. You should also master regular expressions - there are many tutorials. Good luck. Commented Dec 3, 2020 at 14:05

1 Answer 1

1
example.com/random-url-here?mode=grid 

The part of the URL after the first ? (ie. mode=grid in this example) is called the query string.

RewriteRule (.*)$^mode=list $1 [L,R=301] 

The RewriteRule directive takes up to 3 arguments:

RewriteRule pattern substitution [flags] 

The pattern (first argument) to the RewriteRule directive is a regular expression (regex) that matches against the requested URL-path only, which notably excludes the query string. Therefore you can't match the query string using the RewriteRule directive.

To match the query string you need to use an additional RewriteCond (condition) directive and check against the QUERY_STRING server variable. RewriteCond directives apply conditions to the RewriteRule directive that follows.

However, the regex (.*)$^mode=list (apart from trying to match the query string) will never match in this context. $ asserts the end-of-line and ^ asserts the start-of-line - so this will always fail.

In your example above, the $1 backreference (in the substitution string) is attempting to match the URL-path. However, this URL-path (in a directory context, ie. .htaccess) does not start with a slash (ie. it's relative), so will result in a malformed redirect unless you also have a RewriteBase directive defined elsewhere in your .htaccess file. A relative substitution string is seen as a filesystem path relative to the directory that contains the .htaccess file.

If you omit the R (redirect) flag in this context (as in your first example) then it will try to internally rewrite the request (not externally redirect), so the visible URL will not change.

Try the following instead, near the top of your root .htaccess file:

RewriteEngine On RewriteCond %{QUERY_STRING} ^mode=(list|grid)$ RewriteRule (.*) /$1 [QSD,R=302,L] 

The above states... for all URLs (.*) that have a query string of mode=list or mode=grid (exactly) then redirect to the same URL-path and discard the query string (QSD - Query String Discard). The QSD is new to Apache 2.4 (which I assume you are using). If you omit the QSD flag then you will get a redirect loop (since the query string will be re-appended to the redirected URL).

Note that the above matches the query string exactly (as in your examples). If there are any other URL parameters in the query string or the case is different then it will fail to match.

Note that this is a 302 (temporary) redirect. Only change it to a 301 (permanent) - if that is the intention - when you have confirmed that it works OK. 301s are cached persistently by the browser so can make testing problematic.

Reference:

1
  • 1
    wow, what a wonderful gift, and great explanations! thank you so much, this works. highly appreciated Commented Dec 3, 2020 at 22:59

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.