I want to redirect non-www URL to www.
I have one main wordpress website example.com
and an other website in a subdirectory `example.com/sub
The redirection from https://example.com
to https://www.example.com
works
BUT
The redirection from https://example.com/sub
to https://www.example.com/sub
does not.
Main HTaccess
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Sub htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /sub/
RewriteCond %{HTTPS} on [OR]
RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} https
RewriteRule .* - [E=WPR_SSL:-https]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule .* - [E=WPR_ENC:_gzip]
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} =""
RewriteCond %{HTTP:Cookie} !(wordpress_logged_in_. |wp-postpass_|wptouch_switch_toggle|comment_author_|comment_author_email_) [NC]
RewriteCond %{REQUEST_URI} !^(/sub(/(. /)?feed/?. /?|/(?:. /)?embed/|/(index\.php/)?wp\-json(/.*|$)))$ [NC]
RewriteCond %{HTTP_USER_AGENT} !^(facebookexternalhit).* [NC]
RewriteCond "%{DOCUMENT_ROOT}/sub/wp-content/cache/wp-rocket/%{HTTP_HOST}%{REQUEST_URI}/index%{ENV:WPR_SSL}%{ENV:WPR_WEBP}.html%{ENV:WPR_ENC}" -f
RewriteRule .* "/sub/wp-content/cache/wp-rocket/%{HTTP_HOST}%{REQUEST_URI}/index%{ENV:WPR_SSL}%{ENV:WPR_WEBP}.html%{ENV:WPR_ENC}" [L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /sub/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /sub/index.php [L]
</IfModule>
CodePudding user response:
This is very similar to this question that was asked recently: .htaccess redirect entire site from non-www/http to www/https
When the problem is per-directory .htaccess
files, you can prevent the rules in those files from running after some rules by using the [END]
flag. From the documentation:
Using the
[END]
flag terminates not only the current round of rewrite processing (like[L]
) but also prevents any subsequent rewrite processing from occurring in per-directory (htaccess
) context.
So you should be able to use [END]
in your rules to make them take precedence over other rules in the subdirectories:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,END]
CodePudding user response:
The non-www to www redirect in the root .htaccess
file is not processed so the redirect never occurs.
mod_rewrite directives are not inherited (by default) so when you request https://example.com/sub/
, the mod_rewrite directives in /sub/.htaccess
completely override the parent directives (ie. the non-www to www redirect) and the parent directives are not even processed so the redirect does not occur. (In this instance, if the parent directives did get processed then your site would most certainly break anyway.)
You need to repeat the non-www to www redirect in the /sub/.htaccess
file. However, you can't use exactly the same rule (using a backreference) in the subdirectory since you will lose the /sub
directory from the redirect. You need to make use of the REQUEST_URI
server variable instead.
For example, at the top of your /sub/.htaccess
file:
# /sub/.htaccess
# Redirect non-www to www
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
Note that the REQUEST_URI
server variable includes the slash prefix, so the slash is omitted from the substitution string.