Redirects
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:
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:
return [
'johannschopplich.helpers' => [
'redirects' => [
'shop/(:all)' => fn (string $path) => go('https://shop.example.com/' . $path, 301)
]
]
];