Htaccess: add/remove trailing slash from URL
Right below the RewriteEngine On
line, add:
RewriteCond %{REQUEST_FILENAME} !-dRewriteRule ^(.*)/$ /$1 [L,R] # <- for test, for prod use [L,R=301]
to enforce a no-trailing-slash policy.
To enforce a trailing-slash policy:
RewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*[^/])$ /$1/ [L,R] # <- for test, for prod use [L,R=301]
EDIT: commented the R=301
parts because, as explained in a comment:
Be careful with that
R=301
! Having it there makes many browsers cache the .htaccess-file indefinitely: It somehow becomes irreversible if you can't clear the browser-cache on all machines that opened it. When testing, better go with simpleR
orR=302
After you've completed your tests, you can use R=301
.
To complement Jon Lin's answer, here is a no-trailing-slash technique that also works if the website is located in a directory (like example.org/blog/):
RewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_URI} (.+)/$RewriteRule ^ %1 [R=301,L]
For the sake of completeness, here is an alternative emphasizing that REQUEST_URI
starts with a slash (at least in .htaccess
files):
RewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_URI} /(.*)/$RewriteRule ^ /%1 [R=301,L] <-- added slash here too, don't forget it
Just don't use %{REQUEST_URI} (.*)/$
. Because in the root directory REQUEST_URI
equals /
, the leading slash, and it would be misinterpreted as a trailing slash.
If you are interested in more reading:
(update: this technique is now implemented in Laravel 5.5)
This is what I've used for my latest app.
# redirect the main page to landing##RedirectMatch 302 ^/$ /landing# remove php ext from url# https://stackoverflow.com/questions/4026021/remove-php-extension-with-htaccessRewriteEngine on # File exists but has a trailing slash# https://stackoverflow.com/questions/21417263/htaccess-add-remove-trailing-slash-from-urlRewriteCond %{REQUEST_FILENAME} !-dRewriteRule ^/?(.*)/+$ /$1 [R=302,L,QSA]# ok. It will still find the file but relative assets won't load# e.g. page: /landing/ -> assets/js/main.js/main# that's we have the rules above.RewriteCond %{REQUEST_FILENAME} !\.phpRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^/?(.*?)/?$ $1.php