As an example, I was expecting this


to evaluate to an internal rewrite


Why is it showing up on the browser url-bar as a 302 redirect?

RewriteEngine On
#Put in by the hosting company to enforce https
RewriteCond %{HTTP_HOST} example\.software [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.software/$1 [R,L]

#Bunch of domains, not being used yet
RewriteCond %{HTTP_HOST} ^example\.app$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.example\.app$ [NC,OR]
RewriteCond %{HTTP_HOST} ^example\.kiwi$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.example\.kiwi$ [NC,OR]
RewriteCond %{HTTP_HOST} ^example\.nz$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.example\.nz$ [NC,OR]
RewriteCond %{HTTP_HOST} ^example\.online$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.example\.online$ [NC]
RewriteRule ^ https://example.software/$1 [R=302,L]

#Internal redirects
RewriteCond %{HTTP_HOST} ^example.software$ [NC]
RewriteRule ^home$ https://example.software\?mode\=home&%{QUERY_STRING}  [L]
RewriteRule ^contacts$ https://example.software\?mode\=contacts&%{QUERY_STRING}  [L]
RewriteRule ^credits$ https://example.software\?mode\=credits&%{QUERY_STRING}  [L]
RewriteRule ^downloads$ https://example.software\?mode\=downloads&%{QUERY_STRING}  [L]
RewriteRule ^developer$ https://example.software\?mode\=developer&%{QUERY_STRING}  [L]
RewriteRule ^projects$ https://example.software\?mode\=projects&%{QUERY_STRING}  [L]
RewriteRule ^(download)/([^/]+)$ https://example.software?mode=$1&name=$2 [L]
RewriteRule ^(code)/([^/]+)$ https://example.software?mode=$1&name=$2 [L]
RewriteRule ^(payment)/([^/]+)$ https://example.software?mode=$1&name=$2 [L]
RewriteRule ^(donation)/([^/]+)$ https://example.software?mode=payment&name=$2 [L]

Header always set Content-Security-Policy "upgrade-insecure-requests;"
Header append X-Frame-Options: "SAMEORIGIN"
Header append X-Content-Type-Options: "nosniff"
  • Aside: In your #Internal redirects section, the RewriteCond directive only applies to the very first RewriteRule directive that follows. However, it looks like the intention is that it applies to all the RewriteRule directives that follow - but that is not the case. The remaining RewriteRule directives are processed unconditionally (ie. for every domain). To avoid repeating the same condition before every rule, you could instead write an additional rule that skips (S flag) the following rules when the requested Host is not the domain in question.
    – MrWhite
    Oct 1, 2022 at 17:27
  • ... although looking at the preceding rule, if you are redirecting all other domains to the domain in question anyway, then maybe that condition (RewriteCond directive) is perhaps redundant anyway. (Unless you are not redirecting all the domains?)
    – MrWhite
    Oct 1, 2022 at 17:33

1 Answer 1


Your rewrite rules use absolute URLs that include the protocol and host name. Internal rewrites only work with relative URLs that have just the path. When mod_rewrite encounters an absolute URL for the target of the rewrite, it uses a redirect.

So instead of

RewriteRule ^home$ https://example.software\?mode\=home&%{QUERY_STRING}  [L]

You should use

RewriteRule ^home$ /\?mode\=home&%{QUERY_STRING}  [L]

There are some other possible problems with that rule. I don't think so much needs to escaped, rather than using a variable to append the query string, you should use the QSA (query string append) flag, and you probably need to rewrite to your index handler. The correct rewrite is probably going to look like:

RewriteRule ^home$ /index.php?mode=home  [QSA,L]
  • I just changed one of them to test. Its not working for me. To check, I dumped it using console.log (location.search.substring(1) but I don't see anything for the internal redirect. Nov 17, 2021 at 21:43
  • 3
    That code sounds like JavaScript to me. You can't test rewrite rules from JavaScript. You need to use something like curl and your server logs. Nov 17, 2021 at 23:08
  • You could do some debugging in your .htaccess by using e.g.: Header always set X-Your-Header "some info" and inspect that header either in the client console or your server script. Oct 1, 2022 at 7:32
  • Almost a year later, it's obviously all working by now - redirection and headers. But I don't understand your comment. Please explain what you are trying to impart to me. Oct 1, 2022 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.