.htaccessmod-rewriteurl-rewriting

htaccess rewrite: non-www to https://www


I'm trying to improve my website SEO and several online tools have flagged that I need to ensure 301 redirects are configured on my website https://example.co.uk to https://www.example.co.uk. Apparently, Google dings me if the redirects are confirgured properly. When I try to insert some lines of code to address this issue I get issues with my paths after the domain name.

Heres the code I have in my wordpress-vhost-config file. I assume I have some sort of conflict with rewrite rules but don't know what to adjust.

RewriteEngine On
RewriteRule ^bitnami/wordpress(/.*) $1 [L]
# END WordPress fix for plugins and themes
# BEGIN WordPress
# https://wordpress.org/support/article/htaccess/#basic-wp
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

#this is the part that doesn't seem to work
#RewriteCond %{HTTP_HOST} !^www\.
#RewriteCond %{HTTPS}s on(s)|offs()
#RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]

RewriteRule . /index.php [L]

I have inserted this code:

#this is the part that doesn't seem to work
#RewriteCond %{HTTP_HOST} !^www\.
#RewriteCond %{HTTPS}s on(s)|offs()
#RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]

But have it commented it out for now as the URL paths were not working properly.


Solution

  • You've inserted the code in the wrong place. A single "rule" consists of the RewriteRule directive together with the preceding RewriteCond directives (conditions). By placing the new rule where you have you've inserted it in the middle of the existing rule and consequently broken it.

    Your new rule (canonical redirect) needs to go at the very top, immediately after the first RewriteEngine On directive.

    However, your new rule is not strictly correct for a couple of reasons:

    1. It preserves the requested protocol, either HTTP or HTTPS. It should redirect to HTTPS only.
    2. You have implemented a 302 (temporary) redirect. This is OK for testing, however, this ultimately needs to be a 301 (permanent) redirect.

    In other words:

    RewriteEngine On
    
    # Redirect non-www to www (and HTTPS)
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L]
    

    You should also probably implement an HTTP to HTTPS redirect for requests that are already to the correct hostname. This can be implemented as an additional rule following the one above (providing you are not implementing HSTS).

    UPDATE: For example:

    :
    
    # HTTP to HTTPS redirect (following the rule above)
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L]
    

    Heres the code I have in my wordpress-vhost-config file.

    Not sure exactly what you mean by this as this is non-standard. If these rules are being included directly in the <VirtualHost> config (which is what this filename would seem to imply) then all these rules are wrong and it's going to fail horribly (RewriteBase is not permited in a vhost context). So, I assume they are being included inside a <Directory> container (which itself might be inside a <VirtualHost>) and .htaccess files are disabled? (Although you have tagged the question .htaccess?)

    Reference: