How to force trailing slash?

Hey guys, I just realized that the Facebook button treats URLs differently when they end or don’t end with trailing slashes, in regards to maintaining Likes and comments. The best solution I can think of to handle this is to force my website to always be one or the other.

I tried using .htaccess to force trailing slashes but then it caused errors with the Kirby Panel that prevented me from saving changes to pages.

Any ideas?

In .htaccess add your code for forcing trailing slashes right after the “make panel links work” code.

Find:

# make panel links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^panel/(.*) panel/index.php [L]

After add the following, or whatever code you have for trailing slashes:

# redirect to trailing shash (/)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]

Keep in mind that you should also add the trailing slash in the internal links of your website since the kirby functions such as url() do not include a trailing slash. If you don’t do that then a redirect will happen every time somebody clicks a link from one page to another (which will not be noticeable by the users, but it is not a good practice)

I tried this. I could log in to the panel but when I try to save It does not work.

The htaccess-file looks like this:

<IfModule mod_rewrite.c>
RewriteEngine on

RewriteRule ^content/(.*)\.(txt|md|mdown)$ error [R=301,L]
RewriteRule ^site/(.*) error [R=301,L]
RewriteRule ^kirby/(.*) error [R=301,L]

# make panel links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^panel/(.*) panel/index.php [L]

# redirect to trailing shash (/)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]

# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]

</IfModule>

@jenstornell:

I can save content from the panel with the following condition:

# make panel links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^panel/(.*) panel/index.php [L]

# remove trailing slash, but not for the panel
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/panel/.*$
RewriteCond %{REQUEST_URI} (.*)$
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]

# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]

@jensfranke:

RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]

This removes trailing slashes, rather than force them.

To force the slash try this:

# remove trailing slash, but not for the panel
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/panel/.*$
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.+)$ http://%{HTTP_HOST}/$1/ [R=301,L]

This worked great for me until i found this issue and I had to remove it. I found it was adding a trailing slash to my /sitemap.xml so for over a month Google hasn’t been able to reach my sitemap, because /sitemap.xml/ causes a 404.

If anyone can reproduce and fix, that would be awesome.

@jimbobrjames How do you create your sitemap? With a route? If you force a trailing slash but your route does not contain a slash, then yes, this setup will fail.

Nope… the site map plugin

Well, the sitemap plugin uses a route, so that amounts to the same. if you want to force a trailing slash, you either have to adapt the route in that plugin or make an exception to the rewrite rule.

But as i understand the .htaccess rule, its meant to ignore direct access to stuff with an extension isn’t it? Directly accessing an image does not get a trailing slash. Is it because an xml file is a page rather then a file?

Since the request does not match an existing file, Apache continues… The .htaccess is executed before PHP kicks in.

@texnixe noted.

I tried this, and i dont get a trailing slash anymore, but i do get a blank page and no site map…curious…

# force trailing slash, but not for the panel
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/panel/.*$
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/sitemap\.xml$
RewriteRule ^(.+)$ http://%{HTTP_HOST}/$1/ [R=301,L]

Try this:

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

(But don’t ask questions :wink:)

Didn’t fly. Same result :frowning:

Hm, worked for me in a test Starterkit on localhost, but who knows, maybe it does not work in every environment. Then you probably have to dig deeper into rewrite rules.