How to Redirect URLs with Query Parameters
I’ve written extensively on redirecting requests with Apache/.htaccess. This post adds to the stack with some quick examples showing how to redirect URIs that include query parameters, AKA query strings.
Contents
- Key Concepts: Four ways to redirect query strings
- Way 1: Request contains query string, target does not
- Way 2: Target contains a query string
- Way 3: Using the [QSA] flag to combine query strings
- Way 4: Using the [QSD] flag to remove query strings
- Time for some examples
- Example 1: Redirect and remove query string
- Example 2: Redirect and add query string
- Example 3: Redirect and combine query strings
- Example 4: Redirect and remove all query strings
- Related Posts
Key Concepts
Before diving into some examples, it is important to understand how Apache handles URIs that contain query strings. To get there, consider the following rewrite example:
RewriteRule /request/ /target/ [R]
The first pattern specified in the RewriteRule matches against the requested URI. The second pattern in the RewriteRule refers to the target URI. So when discussing the following key concepts, remember that “request” refers to the original requested URI. And that “target” refers to the replacement URI to which we are redirecting.
So what are these mysterious “key concepts”..? Basically just the four ways that Apache handles redirects and rewrites URIs that include query strings. Let’s look at each..
Way 1: Request contains query string, target does not
When the requested URI includes a query string and the target string does not, Apache will append the query string to the target URI. For example, take this requested URI:
https://example.com/request/?query-string
..and use the following rewrite rules to redirect:
RewriteCond %{QUERY_STRING} (query-string) [NC]
RewriteRule /request/ /target/ [R]
..the resulting target (destination) URI will be this:
https://example.com/target/?query-string
Way 2: Target contains a query string
Regardless of whether or not the requested URI contains a query string, if the target URI includes one, it will be used in the target URI (and the original requested query string will be discarded). For example, take this requested URI:
https://example.com/request/?query-string
..and use the following rewrite rules to redirect:
RewriteCond %{QUERY_STRING} (query-string) [NC]
RewriteRule /request/ /target/?new-query-string [R]
..the resulting target URI will be this:
https://example.com/target/?new-query-string
Way 3: Using the [QSA] flag to combine query strings
If both requested URI and target URI contain a query string, we can use the [QSA] flag to combine them into a newly generated query string. For example, take the following requested URI:
https://example.com/request/?old-query-string
..and use the following rewrite rules to redirect:
RewriteCond %{QUERY_STRING} (query-string) [NC]
RewriteRule /request/ /target/?new-query-string [R,QSA]
..the resulting target URI will be this:
https://example.com/target/?new-query-string&old-query-string
Note that “QSA” stands for “Query String Append”. The more you know.
Way 4: Using the [QSD] flag to remove query strings
For Apache versions 2.4 and better, we can remove the requested query string by adding the [QSD] flag. For example, take the following requested URI:
https://example.com/request/?query-string
..and use the following rewrite rules to redirect:
RewriteCond %{QUERY_STRING} (query-string) [NC]
RewriteRule /request/ /target/ [R,QSD]
..the resulting target URI will be this:
https://example.com/target/
Note: “QSD” stands for “Query String Delete”.
Note: If the target URI includes a query string, [QSD] will not remove it. [QSD] removes only the requested query string.
Note: For versions of Apache less than 2.4, we can append a question mark ? (instead of [QSD]) to remove the query string. So for Apache 2.2 and earlier, we would do this:
RewriteCond %{QUERY_STRING} (query-string) [NC]
RewriteRule /request/ /target/? [R]
For more details check out RewriteRule Flags in the official Apache documentation.
Time for some examples
Now that we understand the key concepts for redirecting query strings, let’s look at a few “real-world” examples..
Example 1: Redirect and remove query string
This example redirects requests like the following:
https://example.com/index.php?id=123
We want the target directory to have the same number as specified in the query string:
https://example.com/123/
..where 123 can be any number.
To do this, we can use the following Apache/.htaccess code:
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^/index\.php$ /%1/ [L,R=301]
</IfModule>
After checking that the rewrite module is available, we use RewriteCond to grab the numerical part of the QUERY_STRING. Then we use RewriteRule to match the requested URI and redirect it to the target directory, /%1/. Note that %1 is the variable obtained in RewriteCond that contains the matched numerical value.
Example 2: Redirect and add query string
In this example, we want to redirect requests while adding a new query string. Say we have this URL:
https://example.com/path/123/product/
..and we want to remove the 123 and append it as a query string, like this:
https://example.com/path/product/?id=123
..where 123 can be any number.
To do this, we can use the following Apache/.htaccess code:
<IfModule mod_rewrite.c>
RewriteRule ^/path/([0-9]+)/product/$ /path/product/?id=$1 [L,R=301]
</IfModule>
After checking that the rewrite module is available, we jump right in to the RewriteRule, which matches the numerical part of the URI via ([0-9]+). The matched number is then used in the query string of the target URI. Note the R=301 flag sends a 301 “Permanent” response header, because we want this to be a permanent URI change.
Example 3: Redirect and combine query strings
Here we have a query string in both the requested URI and the target URI, and we want to combine them. For example, if our original URIs look like this:
https://example.com/page/123/?item=001
..and we want our new target URIs look like this:
https://example.com/?page=123&item=001
Then we can use the following code to make it happen:
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ^item=([0-9]+)$
RewriteRule ^/page/([0-9]+)/$ /?page=$1&item=%1 [R=301,QSA]
</IfModule>
After checking that the rewrite module is available, we use RewriteCond to grab the numerical part of the QUERY_STRING. Then we use RewriteRule to match the requested URI and redirect it to the target directory. The key to making this work, is the addition of the [QSA] flag, which instructs Apache to combine the requested query string with the new target query string.
Example 4: Redirect and remove all query strings
Our last example shows how to remove query strings while redirecting to a new location. Say we have the following URL:
https://example.com/path/?page=1&item=001&key=abc
After our new site redesign, we no longer need the crazy query strings. So to remove them, we add the following directives to Apache config or root .htaccess file:
<IfModule mod_rewrite.c>
RewriteRule (.*) /$1/ [R,QSD]
</IfModule>
Here we use RewriteCond to get the requested path, which then is used to specify the target URI (via the $1 variable). And as you may have guessed, we are using the QSD flag to remove all query strings.
Note: The above examples show how to redirect requests. To instead rewrite requests, check out our tutorial, How to Shorten any URL with Apache/.htaccess.
Related
Want more redirecting examples? Check out these posts here at .htaccess made easy and at my blog site Perishable Press.