Redirect Query String via .htaccess

.htaccess made easy

In general, redirecting URLs is a piece of cake with Apache’s .htaccess. The only trick is redirecting based on the URL’s query-string value. Doing so requires slightly different directives that many people are not aware of, so it’s common to see a questions like, “why isn’t my redirect working for query strings?” This quick tutorial aims to clear up any confusion and explains how to redirect any URL based on its query string.

Query Strings in URLs

What are we talking about when we say “query string”? Here are some examples:

http://example.com/index.php?this=is-a-query-string
http://example.com/directory/?and=this-is-a-query-string
http://example.com/path/?also-a-query-string

So basically anything included after the first question mark, ?, is considered the query string. So for those three URLs, the query strings would be:

this=is-a-query-string
and=this-is-a-query-string
also-a-query-string

Notice the query strings can have a key and value (first two examples), or just a key with no value (third example). Either way, it makes no difference to Apache, because it treats the entire query string — whatever it may be — as a single string. That is, Apache makes no distinction between keys and values; the query string simply is whatever comes after the first question mark in the URL. This greatly simplifies things when it comes to redirecting based on query strings.

Redirecting query strings

To redirect based on the URL’s query string, we must use Apache’s mod_rewrite. Unfortunately, mod_alias does not recognize query strings. But no problem, mod_rewrite is super powerful and provides a LOT of flexibility to get the job done.

Here is the basic technique for redirecting a URL based on the value of its query string:

# Redirect Query String
<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteCond %{QUERY_STRING} key=value
	RewriteRule (.*) /path/ [R=302,L]
</IfModule>

Here is what’s happening in this rule set, line by line:

  1. <IfModule mod_rewrite.c> – Check if mod_rewrite is available
  2. RewriteEngine On – Enable the rewrite engine (if not already enabled)
  3. RewriteCond %{QUERY_STRING} key=value – Check the value of QUERY_STRING for the string, key=value
  4. RewriteRule (.*) /path/ – For any matching URLs, redirect the request to /path/
  5. [R=302] – Send a 302 “Temporary” header along with the response
  6. [L] – Instruct Apache to stop processing this rule set
  7. </IfModule> – Close the check for mod_rewrite

That’s the basic idea. If you are familiar with regular expressions (regex) and mod_rewrite, you can pretty much stop reading here. Otherwise, continue reading for some examples showing how to customize the redirect however is necessary.

Example 1: Target query string of a specific URL

In the previous (basic) example, we are matching any URL that has a query string that contains the specified string, key=value. Here is how to limit the redirect to only a specific URL:

# Redirect Query String
<IfModule mod_rewrite.c>
	RewriteCond %{REQUEST_URI} ^/specific/url/
	RewriteCond %{QUERY_STRING} key=value
	RewriteRule (.*) /path/ [R=301,L]
</IfModule>

This does the same thing as before, only now the redirect will happen only if the requested URL begins with /specific/url/. Hence the caret ^ indicates the beginning of the REQUEST_URI variable. Note also that here we change the status code for the redirect from 302 to 301.

Example 2: Redirect more than one query string

Now say that we want to redirect any query string that includes any of the following:

key=value-01
key=value-02
key=value-03
.
.
.

..such that any number appended to key=value- will match and redirect. Here is the code:

# Redirect Query String
<IfModule mod_rewrite.c>
	RewriteCond %{QUERY_STRING} key=value-([0-9]+) [NC]
	RewriteRule (.*) /path/ [R=302,L]
</IfModule>

The trick here is using ([0-9]+) to match any number of numerical digits, 0 thru 9. Also note that the [NC] flag makes the match case-insensitive.

Example 3: Include the query string in the redirect URL

Lastly, here is an example that shows how to include the value of the matched query string in the URL to which the request will be redirected. To illustrate, say we want to redirect these URLs:

http://example.com/directory/?key=value-01
http://example.com/directory/?key=value-02
http://example.com/directory/?key=value-03
.
.
.

..to these target files:

http://example.com/directory/file-01.html
http://example.com/directory/file-02.html
http://example.com/directory/file-03.html
.
.
.

..such that the matching number is used in the target file name. Here is the magic code to make it happen:

# Redirect Query String
<IfModule mod_rewrite.c>
	RewriteCond %{QUERY_STRING} key=value-([0-9]+) [NC]
	RewriteRule (.*) /directory/file-%1.html? [R=301,L]
</IfModule>

Here we are using the same basic technique as in previous examples. There are two important things happening here:

  • %1 – Returns the value of the number matched in the RewriteCond
  • ? – Instructs Apache to remove the query string from the target URL

Hopefully these examples enable you to customize your own query-string redirects. If you have any questions, feel free to ask via the comments section below.