Redirects

Send requests for URLs that no page or route answers to a new address, matched with Kirby route patterns.

The redirects option maps a route pattern to a target. A rule fires only where Kirby would otherwise render the error page, so a page or route that exists is never redirected:

site/config/config.php
return [
    'johannschopplich.helpers' => [
        'redirects' => [
            'about-us' => 'about',
            'blog/(:any)' => 'news/$1',
            'archive/(:num)/(:any)' => 'news/$2?year=$1',
            'work/(:any)' => fn (string $slug) => page('projects')?->find($slug)?->url()
        ]
    ]
];

Only GET requests are redirected, with status 302. Rules are tried in order, and the first match wins.

Patterns

A pattern is matched against the whole path, without the leading slash. Kirby's placeholders match one segment each, except (:all), which matches the rest of the path, slashes included.

Matching is case-sensitive. On a multi-language site, the path keeps its language prefix, so blog/(:any) does not match /de/blog/post – add a de/blog/(:any) rule for it.

Targets

A string target is a path or a full URL. $1, $2, and so on insert the segments the placeholders matched, in order.

A closure receives the matched segments as arguments and returns the target. One that returns null redirects nowhere, and the error page renders as usual. For a permanent redirect, call go() with the status yourself:

site/config/config.php
return [
    'johannschopplich.helpers' => [
        'redirects' => [
            'shop/(:all)' => fn (string $path) => go('https://shop.example.com/' . $path, 301)
        ]
    ]
];