Route Handlers Don't Match with Trailing Slashes

In my staging/production environments, Kirby routes don’t correctly match against URLs that have a trailing slash.

Given a sample route (set in config.php):

    [
        'pattern' => 'test',
        'action' => function() {
            return go('other-place', 301);
        }
    ],

Kirby will correctly handle this if the URL is example.com/test but will give a 404 for example.com/test/ .

My local dev environment doesn’t have this weird behavior and the route will be used in both cases.

What’s throwing me off is that my local environment and staging/production environments should be nearly identical. All environments are running identical Docker images (with PHP 7.1, nginx).

Staging/Production are behind a load balancer and in a Kubernetes cluster. My local dev environment is merely running a Docker image on my Mac.

I considered just adding an nginx config statement to strip out trailing slashes and rewrite, but it seems super hacky and without creating an exception for /panel/ actually breaks the panel (it seemingly requires the trailing slash).

Any suggestions on where I should start digging to figure out why trailing slashes are throwing off Kirby routes?

Why not make the trailing slash optional in your route to cover both cases?

1 Like

Well, that was a simple fix. Thanks!

I changed the routes to something like this and they seem to work fine.

    [
        'pattern' => 'test(/?)',
        'action' => function() {
            return go('other-place', 301);
        }
    ],

I actually assumed this behavior was implicitly handled by the router automatically.

Is it just me that assumes that example.com/test and example.com/test/ should always be treated as the same thing? Is there a way to make this behavior the “default”? I feel compelled to pepper all of my routes with a trailing (/?) now.

I think it would actually make sense to reroute one of them to the other in order to avoid duplicate content. You can do so in your server config or .htaccess.

Here are some more links that might be useful:

That’s a totally fair point, especially for routes where visit() is being used.

Right now, I’m mostly concerned with redirecting legacy WordPress urls (which tries to add trailing slashes to everything), so I want to be generous with what I’m matching against.