Question

I want my WordPress website to load with https + non-www and without trailing slashes. I put the following code in .htaccess file:

<IfModule mod_rewrite.c>
 RewriteEngine On
 # Remove trailing slash from non-filepath urls
 RewriteCond %{REQUEST_URI} /(.+)/$
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule ^ https://example.com/%1 [R=301,L]
 # Force HTTPS and remove WWW
 RewriteCond %{HTTP_HOST} ^www\.(.*)$ [OR,NC]
 RewriteCond %{https} off  
 RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
</IfModule>
  1. These rules work fine but I can't remove multiple slashes after the domain. The website loads: https://example.com///// and I want it to redirect to https://example.com

  2. Also, these rules work if they are only in the beginning of the .htaccess file and when I re-save the permalinks the rules disappear...

Could you help me, please

Was it helpful?

Solution

To reduce multiple slashes at the start of the URL-path (or in fact anywhere in the URL-path) to a single slash (there is always at least 1 slash at the start of the URL-path, even if you can't see this is the browser's address bar) then you can use a directive like the following:

# Reduce multiple slashes to single slashes
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule (.*) /$1 [R=301,L]

This uses the fact that the URL-path matched by the RewriteRule pattern has already had multiple slashes reduced. The preceding condition checks that there were multiple slashes somewhere in the URL-path in the initial request.

You would place the above rule second, between your existing rules. And modify your 1st rule that removes the trailing slash to also reduce multiple slashes, thus preventing an unnecessary additional redirect should a request contain both multiple slashes and a trailing slash. For example:

# Remove trailing slash from non-directory URLs AND reduce multiple slashes
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+)/$ https://example.com/$1 [R=301,L]

# Reduce multiple slashes to single slashes
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule (.*) https://example.com/$1 [R=301,L]

# Force HTTPS and remove WWW
RewriteCond %{HTTP_HOST} ^www\. [OR,NC]
RewriteCond %{https} off  
RewriteRule (.*) https://example.com/$1 [R=301,L]

I just tidied the regex in the RewriteCond directive that checks against the HTTP_HOST server variable. ^www\.(.*)$ can be simplifed to ^www\. since you are not making use of the backreference here.

You do not need the <IfModule> wrapper.

Clear your browser cache before testing and preferably test first with 302 (temporary) redirects to avoid potential caching issues.

  1. Also, these rules work if they are only in the beginning of the .htaccess file and when I re-save the permalinks the rules disappear...

These rules certainly need to go near the beginning of the .htaccess file, before the WordPress front-controller.

However, they must go before the # BEGIN WordPress section. Not inside this block, otherwise they will be overwritten since WP itself maintains this code block.

They should not be overwritten if placed before the # BEGIN WordPress comment marker.

OTHER TIPS

to prevent WordPress from modifying your .htaccess, you can also do

add_filter('flush_rewrite_rules_hard', '__return_false');

A "hard" flush updates .htaccess (Apache) or web.config (IIS).

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top