Spring Sale! Save 30% on all books w/ code: PLANET24
Web Dev + WordPress + Security

Redirect Query String via .htaccess

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 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 rewrite URL

Removing the query string

To remove the query string from the rewrite URL for Apache 2.2, use the question-mark technique described in the previous section. To remove the query string for Apache version 2.4+, you must use the [QSD] flag instead. For example, here is the same technique as before, only rewritten for compatibility with Apache 2.4:

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

Notice the QSD in the RewriteRule? That’s the ticket for Apache 2.4 and better. Also note that we removed the question mark ? from the rewrite URL; otherwise it would have triggered an error.

Until next time..

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.

About the Author
Jeff Starr = Web Developer. Book Author. Secretly Important.
SAC Pro: Unlimited chats.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
BBQ Pro: The fastest firewall to protect your WordPress.
Thoughts
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
2024 is going to make 2020 look like a vacation. Prepare accordingly.
First snow of the year :)
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.