Htaccess 404 not working as expected when adding trailing slash

I will try to explain my problem as clearly as possible.

I have a website with cleanup urls that is redirected via .htaccess. The website is expected to be bilingual (fr | en). (

With htaccess, I add forward slashes to everything ( => etc.)

I also have a 404Handling error to redirect to the fr / 404.php error page.

The problem is I am trying to handle error pages in "virtual" folders (level 2 and +), it adds a lot of .php at the end. Example: => .php.php.php.php.php.php.php / (This page doesn't exist, but I want to land on fr / 404.php page).

htaccess handles the first level correctly ( => ), but not the subsequence levels ...

Here's the htaccess file (cleaned up, sorry for the french comments :)):

Options +FollowSymlinks
RewriteEngine On

RewriteBase /

DirectoryIndex index.php

# Error
ErrorDocument 404 /fr/404.php

# Add ending slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ %{REQUEST_URI}/ [R=301,L] 

# (Don't mind thoses next lines until #END, problem isn't here :) )
# Boutique en ligne 
RewriteRule ^(en|fr)/([0-9a-zA-Z+_-]*)-([0-9]*)/$                       $1/boutique.php?cid=$3 [L]
RewriteRule ^(en|fr)/([0-9a-zA-Z+_-]*)/([0-9a-zA-Z+_-]*)-([0-9]*)/$     $1/fiche.php?id=$4 [L]
# Page principales  
RewriteRule ^(en|fr)/acces-client/$             $1/acces-client/ [L]
RewriteRule ^(en|fr)/acces-client/(.*)/$        $1/acces-client/$2.php [L]
RewriteRule ^(en|fr)/boutique-en-ligne/$        $1/boutique.php [L]
# END 

RewriteRule ^(en|fr)/(.*)/(.*)/$                $1/$3.php [L]
RewriteRule ^(en|fr)/(.*)/$                     $1/$2.php [L]
RewriteRule ^(en|fr)/$                          $1/index.php [L]


I know the last three lines are problematic. (This is the only way to find multiple levels of virtual folders ...)

My physical file structure on the server:

    fr (folder)
        - index.php
        - contact.php
        - boutique.php
        - fiche.php
        - etc
    -en (folder) (which isn't complete yet, but will get all same structure as fr)


So, whatever the virtual level (level 1, level 2 or level 3), all "real" files are in the "fr" folder.

Here are 3 examples:

Level 1 - (404 = OK: )

Level 2 - (404 NOT OK: )

Level 3 - (404 NOT OK: )

If you need more clarification / explanation, feel free to ask! (Code changes are also welcome!)

thanks a lot for your help!


source to share

1 answer

This is due to your final slash rule. Change this rule to:

# Add ending slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^.]+?[^/.]$ %{REQUEST_URI}/ [R=302,L]


This will avoid adding a trailing slash if you have a period in your URL.



All Articles