I need to preserve all user query strings.

RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^$ index.html?page=home&%1

RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^about$ index.html?page=about&%1

RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^contact$ index.html?page=contact&%1

How can I specify the RewriteCond for all RewriteRules ?

I am not looking forward to single all-purpose controller RewriteRule since this is a small static website.


For your three examples, these will work:

RewriteRule ^$ index.html?page=home [QSA,L]
RewriteRule ^about$ index.html?page=about [QSA,L]
RewriteRule ^contact$ index.html?page=contact [QSA,L]

The trick is the "QSA" flag.

edit: a slightly more-general solution, this based on how Drupal does it:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html?page=$1 [L,QSA]

The !-f is important, because otherwise you couldn't serve images or index.html itself. The !-d line can be dropped, depending on what, exactly, you're doing. A slightly-different approach might be:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)$ index.html?page=$1 [L,QSA]

which would catch /foo and /bar, but not /foo/, /bar/, or /foo/bar.

  • QSA was what I was looking for ! I dont know how I missed that in the docs. Thanks. – MotionGrafika Jul 21 '10 at 13:24

Beside the fact that you can use QSA, are you aware that you can use %{QUERY_STRING} right within your RewriteRule?:

RewriteRule ^$ index.html?page=home&%{QUERY_STRING}
RewriteRule ^about$ index.html?page=about&%{QUERY_STRING}
RewriteRule ^contact$ index.html?page=contact&%{QUERY_STRING}

The advantage of this method over the QSA flag is that you can control the order of parameters in the resulting querystring. E.g.:

    RewriteRule ^contact$ index.html?%{QUERY_STRING}&page=contact

This makes sure that the 'page' parameter is always set to 'contact', even if it is already contained in the original querystring. (At least this is true for PHP as the querystring parser of PHP always returns the last of multiple identical parameters into the $_GET array.)

One RewriteCond for multiple RewriteRules

Your headline implies another question that can be solved too:

You can use the RewriteRule flag S|skip to tie multiples RewriteRules to a single RewriteCond (or to a set of RewriteConds). Here is an example that applies one Cond to three Rules:

RewriteCond  %{HTTP_HOST}  !^www.mydomain.com$  [NC]
# skip rules if NOT within domain - only way to tie multiple rules to one cond
RewriteRule  .?  -  [S=3]
RewriteRule  ^path1(/.*)$  /otherpath1$1
RewriteRule  ^path2(/.*)$  /otherpath2$1
RewriteRule  ^path3(/.*)$  /otherpath3$1

But this is no solution to your original problem, as backreferences to the RewriteCond (like %1 in your case) will not work within the skipped rules.

  • This actually answers the question 'One RewriteCond for multiple RewriteRules'. – kasimir Aug 8 '14 at 9:56

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.