I would like to redirect the non-https and non-www versions my domain to the https and www version of it. I'm a bit confused by the options. Are these redirect rules equal for my purpose?

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
# Are the following 3 rules equal in effect?
RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [L,R=301]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}{REQUEST_URI} [R=301,L]

Which one should I use?

  • 1
    Far simpler: RedirectPermanent / https://www.example.com in the www.example.com:80 VirtualHost block. mod_rewrite is a great tool but far too much for simple redirections. Jul 16 '18 at 17:33
  1. RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [L,R=301] 2. RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L] 3. RewriteRule ^(.*)$ https://www.%{HTTP_HOST}{REQUEST_URI} [R=301,L]

These 3 rules are essentially the same and will do the same job in most situations, however, #1 is arguably "better" as it canonicalises a FQDN (where the hostname ends in a dot) and would therefore be the preferred version. (Assuming you have no other directives that do this.)

In a .htaccess context, where the .htaccess file is located in the document root then #2 and #3 are identical. (However, in a server or virtual host context then #2 is technically incorrect, as it would result in a double slash after the hostname.)

If the .htaccess was located in a subdirectory then rule #2 would not be correct as it would omit the subdirectory from the redirect. Either #1 or #3 (that use REQUEST_URI) would be required here.

All 3 versions (together with the RewriteCond directive) assume you have no other subdomains, since anything other than www. is redirected.

  1. RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [L,R=301]
  • There is no need for a capturing subpattern (denoted by the surrounding parentheses) in the regex if there is no backreference (eg. $1) in the substition. You are using the REQUEST_URI server variable instead.
  • The regex .* could also be simplified and made more efficient, since you don't need to match anything, you just need to be successful for everything. The regex .* traverses the entire URL-path and matches everything. Whereas a regex like ^ simply asserts the start-of-string, so is immediately successful without actually matching anything.
  • The order of the flags L and R do not matter. However, for consistency, I always include the L (last) flag last.

In other words:

RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
  • 1
    I really appreciate the effort to help us learn, than just providing a solution.
    – IXN
    Jul 16 '18 at 9:24

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.