.htaccessmod-rewritetrailing-slash

Add trailing slash at dynamic .htaccess


I have a site with a big .htaccess with a lot of dynamic rules, everything works fine, but unfortunately, Google is duplicating my URLs, considering the same URL with trailing slash and without... I will paste the code of my .htaccess if someone could help me to enforce adding the trailing slash, without generating a 301 loop.

#Options -MultiViews
RewriteEngine On
RewriteCond %{SERVER_PORT} 443
RewriteRule ^(.*)$ http://www.advogadosaqui.com.br/$1 [R=301,L]

RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

## Adding a trailing slash <<<< (HERE IS WHATS I TRIED) >>>>
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301]

# external redirect rule to remove /artigos/ from URLs
RewriteCond %{THE_REQUEST} \s/artigos/(\S*)\sHTTP [NC]
RewriteRule ^ /%1 [L,R=301]

# external redirect rule to remove /unidades/pagina_agencia/ from URLs
RewriteCond %{THE_REQUEST} \s/+unidades/pagina_agencia/(\S*)\sHTTP [NC]
RewriteRule ^ /%1 [L,R=301]

# external redirect rule to remove /unidades/pagina_locker/ from URLs
RewriteCond %{THE_REQUEST} \s/+unidades/pagina_locker/(\S*)\sHTTP [NC]
RewriteRule ^ /%1 [L,R=301]

# external redirect rule to remove /unidades/pagina_estado/ from URLs
RewriteCond %{THE_REQUEST} \s/+unidades/pagina_estado/(\S*)\sHTTP [NC]
RewriteRule ^ /%1 [L,R=301]

# external redirect rule to remove /unidades/pagina_cidade/ from URLs
RewriteCond %{THE_REQUEST} \s/+unidades/pagina_cidade/(\S*)\sHTTP [NC]
RewriteRule ^ /%1 [L,R=301]

# external redirect rule to remove /unidades/pagina_bairro/ from URLs
RewriteCond %{THE_REQUEST} \s/+unidades/pagina_bairro/(\S*)\sHTTP [NC]
RewriteRule ^ /%1 [L,R=301]

# Remove .php extension externally
# To externally redirect /dir/file.php to /dir/file
# %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
#RewriteRule ^ /%1 [R=301,NE,L]

#Hide and Redirect Extension
RewriteCond %{THE_REQUEST} ^[A-Z]+\s.+\.php\sHTTP
RewriteRule ^(.+)\.php$ /$1 [R=301,L]

# internal rewrite from root to /artigos/
RewriteCond %{HTTP_HOST} advogadosaqui [NC]
RewriteCond %{DOCUMENT_ROOT}/artigos/$1.php -f
RewriteRule ^([\w-]+)/?$ artigos/$1.php [L]

# internal rewrite from root to /unidades/pagina_agencia/
RewriteCond %{HTTP_HOST} advogadosaqui [NC]
RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_agencia/$1.php -f
RewriteRule ^([\w-]+)/?$ unidades/pagina_agencia/$1.php [L]

# internal rewrite from root to /unidades/pagina_locker/
RewriteCond %{HTTP_HOST} advogadosaqui [NC]
RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_locker/$1.php -f
RewriteRule ^([\w-]+)/?$ unidades/pagina_locker/$1.php [L]

# internal rewrite from root to /unidades/pagina_estado/
RewriteCond %{HTTP_HOST} advogadosaqui [NC]
RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_estado/$1.php -f
RewriteRule ^([\w-]+)/?$ unidades/pagina_estado/$1.php [L]

# internal rewrite from root to /unidades/pagina_cidade/
RewriteCond %{HTTP_HOST} advogadosaqui [NC]
RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_cidade/$1.php -f
RewriteRule ^([\w-]+)/?$ unidades/pagina_cidade/$1.php [L]

# internal rewrite from root to /unidades/pagina_bairro/
RewriteCond %{HTTP_HOST} advogadosaqui [NC]
RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_bairro/$1.php -f
RewriteRule ^([\w-]+)/?$ unidades/pagina_bairro/$1.php [L]

# handle .php extension internally
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{DOCUMENT_ROOT}/$1.php -f
#RewriteRule ^(.+?)/?$ $1.php [L]

# remove .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

##ErrorDocument 404 https://www.advogadosaqui.com.br/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . / [L,R=301]

I tried to add this rule, but it's generating a 301 loop:

## Adding a trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=301]

UPDATED Question

After using Anubhava's rules everything works fine without any 301 loopings, the problem is when the request comes without the trailing slash... because now it's generating one unnecessary 301 to enforce the trailing slash, I need to find a way to do it with only one redirect...

Some prints to explain what's going on:

###FIRST JUMP - THE REQUESTED URL

enter image description here

###SECOND JUMP

enter image description here

###LAST JUMP

enter image description here

Instead of this, I need to do one redirect directly to the URL with: https + www + trailing slash

FINAL UPDATE

Ok I found a solution... using page rules in Cloudflare / removing the enforce https and www from the local file (.htaccess) and changing the rules to add a trailing slash to:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)([^/])$ /$1$2/ [L,R=301]

The final .htaccess looked like this:

Options -MultiViews
RewriteEngine On

# Adding a trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)([^/])$ /$1$2/ [L,R=301]

# external redirect rule to remove /artigos/ from URLs
RewriteCond %{THE_REQUEST} \s/artigos/(\S*)\sHTTP [NC]
RewriteRule ^ /%1 [L,R=301]

# Remove .php extension externally
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1/ [R=301,NE,L]

# internal rewrite from root to /artigos/
RewriteCond %{DOCUMENT_ROOT}/artigos/$1.php -f
RewriteRule ^([\w-]+)/?$ artigos/$1.php [L]

# handle .php extension internally
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

By doing this I managed to avoid the extra redirect ;)


Solution

  • You have a massive .htaccess. I will try to combine and merge few rules to shorten the length and also handle adding slash removal:

    Options -MultiViews
    RewriteEngine On
    
    ## Adding a trailing slash
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule [^/]$ https://www.avantitecnologiati.com.br%{REQUEST_URI}/ [L,R=301,NE]
    
    ## add www and turn on https in same rule
    RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
    RewriteCond %{HTTPS} !on
    RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
    RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
    
    # external redirect rule to remove /unidades/pagina_agencia/ from URLs
    RewriteCond %{THE_REQUEST} \s/+(?:artigos|unidades/pagina_(?:agencia|locker|estado|cidade|bairro))/(\S*)\sHTTP [NC]
    RewriteRule ^ /%1 [L,R=301,NE]
    
    # Remove .php extension externally
    RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
    RewriteRule ^ /%1/ [R=301,NE,L]
    
    # internal rewrite from root to /artigos/
    RewriteCond %{DOCUMENT_ROOT}/artigos/$1.php -f
    RewriteRule ^([\w-]+)/?$ artigos/$1.php [L]
    
    RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_agencia/$1.php -f
    RewriteRule ^([\w-]+)/?$ unidades/pagina_agencia/$1.php [L]
    
    RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_locker/$1.php -f
    RewriteRule ^([\w-]+)/?$ unidades/pagina_locker/$1.php [L]
    
    RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_estado/$1.php -f
    RewriteRule ^([\w-]+)/?$ unidades/pagina_estado/$1.php [L]
    
    RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_cidade/$1.php -f
    RewriteRule ^([\w-]+)/?$ unidades/pagina_cidade/$1.php [L]
    
    RewriteCond %{DOCUMENT_ROOT}/unidades/pagina_bairro/$1.php -f
    RewriteRule ^([\w-]+)/?$ unidades/pagina_bairro/$1.php [L]
    
    # handle .php extension internally
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule ^(.+?)/?$ $1.php [L]
    

    Make sure to use a different browser or remove cache data from your browser to test this rule to avoid old cache.