# Remove "/" to "/dashboard"
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule (.*) $1%1/ [L]
This doesn't "remove" anything. In fact, it will append a trailing slash to the end of the URL-path and query string, which seems a bit random?
However, you can't simply remove the trailing slash that occurs after a physical directory in the URL-path, since mod_dir will try to append it with a 301 redirect in order to "fix" the URL.
You can prevent mod_dir from appending the trailing slash with the DirectorySlash Off
directive. However, you then need to manually append the trailing slash to the directory with an internal rewrite in order to correctly serve the "index file" (ie. the DirectoryIndex
document).
I'm assuming you are linking to the directory without a trailing slash in your internal links.
Try the following instead in the root .htaccess
file:
# Disable directory listings (mod_autoindex)
Options -Indexes
# Prevent mod_dir appending trailing slash to directories
DirectorySlash Off
RewriteEngine On
# Rewrite the URL to append a trailing slash to directories (internally)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*[^/])$ $1/ [L]
A request for /dashboard
(no trailing slash) that maps to a physical directory will be internally rewritten to /dashboard/
, which will allow the "index file" to be served (by mod_dir also).
For security reasons, you need to ensure that directory listings (mod_autoindex) are disabled, otherwise, directory listings could potentially be generated for directories even when they contain a directory index document. See the security warning in the Apache docs under the DirectorySlash
directive.
You need to ensure that your browser cache is cleared before testing since the 301 (permanent) redirect by mod_dir (to append the trailing slash) will have certainly been cached by the browser.
Remove the trailing slash (optional)
You could implement a canonical redirect to actually "remove" the trailing slash from the URL, should there be any requests from third parties (or search engines) that include the trailing slash. (It should already be removed on all your internal links, so this is not required to make your site "work", however, it could be required for SEO to avoid potential duplicate content.)
I'm assuming you don't want the trailing slash on any URL.
You should add the following "redirect" before the rewrite above, immediately after the RewriteEngine
directive.
# Remove the trailing slash, should it appear on any 3rd party requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)/$ /$1 [R=301,L]
The check against the REDIRECT_STATUS
environment variable is to ensure we do not redirect the already written request (that appends the trailing slash) by the later rewrite, during the second pass of the rewrite engine. Alternatively, you could use the END
flag (Apache 2.4) on the later rewrite.
UPDATE:
.htaccess
file not in the root directory
The above assumes the .htaccess
file is located in the document root (and therefore applies to all directories and subdirectories thereof). If, however, the .htaccess
file is in a subdirectory then you will need to modify the external redirect (that "removes" the trailing slash), since the RewriteRule
pattern matches the URL-path relative to the directory that contains the .htaccess
file, not the root directory.
So, if the .htaccess
file is located in a subdirectory then use the following "redirect" instead:
# Remove the trailing slash, should it appear on any 3rd party requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+)/$
RewriteRule /$ /%1 [R=301,L]
This requires an additional condition (RewriteCond
directive) to capture the relevant part of the URL-path from the REQUEST_URI
server variable (that contains the full root-relative URL-path), instead of the RewriteRule
pattern, which will omit the parent directory(s). The %1
backreference (as opposed to $1
) references the captured subpattern from the preceding condition (RewriteCond
directive), as opposed to the RewriteRule
pattern.
Incidentally, this will also work if the .htaccess
file is in the document root.
Note that this is unable to "remove" the trailing slash from the subdirectory (that contains the .htaccess
file) itself. For that you would need to make use of the .htaccess
file in the parent directory (ie. document root).
Summary
The complete .htaccess
would then become:
# Disable directory listings (mod_autoindex)
Options -Indexes
# Prevent mod_dir appending trailing slash to directories
DirectorySlash Off
RewriteEngine On
# Remove the trailing slash, should it appear on any 3rd party requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+)/$
RewriteRule /$ /%1 [R=301,L]
# Rewrite the URL to append a trailing slash to directories (internally)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*[^/])$ $1/ [L]
Note there is no RewriteBase
directive here.