Skip to content

Redirects via config file#16355

Merged
brandonkelly merged 24 commits into5.6from
feature/redirects
Jan 11, 2025
Merged

Redirects via config file#16355
brandonkelly merged 24 commits into5.6from
feature/redirects

Conversation

@timkelty
Copy link
Copy Markdown
Contributor

@timkelty timkelty commented Dec 23, 2024

Description

Adds configurable redirects via config/redirects.php that are only parsed just before serving a 404, so there isn't any added work for normal route/controller requests.

By default, redirects are 302 (temporary) and match the full request path (Craft::$app->getRequest()->getFullPath()) with leading and trailing slashes removed. Yii's URL rule pattern match replacement can be used in to/from.

Matching logic can be overridden via \craft\web\RedirectRule::match callback. When match is used, to, from, and caseSensitive are ignored.

Also provides a \craft\web\ErrorHandler::EVENT_BEFORE_REDIRECT event, should any plugins want to know about a handled redirect.

<?php

return [
    // Path match (case-insensitive by default)
    'redirect/from' => 'redirect/to',

    // Path match with Yii URL Rule named parameters
    // https://www.yiiframework.com/doc/guide/2.0/en/runtime-routing#named-parameters
    'redirect/from/foo/<bar:{slug}>' => 'redirect/to/<bar>',

    // Path match (case-sensitive)
    [
        'from' => 'redirect/FROM/<year:\d{4}>/<month>',
        'to' => 'https://redirect.to/<year>/<month>',
        'caseSensitive' => true,
    ],

    // Custom match callback
    [
        'match' => function (\Psr\Http\Message\UriInterface $url): ?string {
            parse_str($url->getQuery(), $params);

            return isset($params['bar'])
                ? sprintf('redirect/to/%s', $params['bar'])
                : null;
        },
        'statusCode' => 301,
    ],
];

@timkelty timkelty marked this pull request as ready for review December 23, 2024 15:41
@timkelty timkelty marked this pull request as draft January 7, 2025 22:22
@timkelty timkelty marked this pull request as ready for review January 8, 2025 02:48
@brandonkelly brandonkelly changed the base branch from 5.x to 5.6 January 11, 2025 03:23
@brandonkelly brandonkelly merged commit 62d99d8 into 5.6 Jan 11, 2025
@brandonkelly brandonkelly deleted the feature/redirects branch January 11, 2025 18:11
@michtio
Copy link
Copy Markdown
Contributor

michtio commented Mar 17, 2025

@timkelty am I correct in assuming this only allows for path matches and not url matches e.g. in case of a multisite setup with different domain names?

@timkelty
Copy link
Copy Markdown
Contributor Author

@timkelty am I correct in assuming this only allows for path matches and not url matches e.g. in case of a multisite setup with different domain names?

match gives you full control if want to match on anything else:

        'match' => function (\Psr\Http\Message\UriInterface $url): ?string {
           if ($url->getHost() === 'mysite.com') {
               return $url->withHost('en.mysite.com');
           }

           return null;
        },

@michtio
Copy link
Copy Markdown
Contributor

michtio commented Mar 17, 2025

Thank you for claryfing @timkelty!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants