Htaccess: add/remove trailing slash from URL Htaccess: add/remove trailing slash from URL php php

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 simple R or R=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