Redirecting old URL to the new one with 301 on the same domain

I am trying to redirect old URLs with 301 response status. I am using Sim 4. I checked some previous topic, like: 214 but it’s not working for me.
My code:

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\App;

return function (App $app) {
    $app->get('/', \App\Action\HomeAction::class)->setName('home');

    // redirects
    $app->get('/old-url', function (ServerRequestInterface $request, ResponseInterface $response) {
        return $response->withRedirect('/new-url')->withStatus(301);
    });    

Of course, I get error because ResponseInterface doesn’t have withRedirect method.

When I check Response - Slim Framework there is usage of header Location which is I guess not my case, because I am not changing domain, just redirecting within the same domain.

How would you redirect in Slim 4 within the same domain from old URL to the new one?
Thank you.

You can also pass a relative or absolute URL path as a new location:

301 Moved Permanently

return $response
  ->withHeader('Location', '/new-path')
  ->withStatus(301);

To respect the basePath and output the URL for a given route you can use the RouteParser:

use Slim\Routing\RouteContext;

// Get RouteParser from request to generate the urls
$routeParser = RouteContext::fromRequest($request)->getRouteParser();

$location = $route->urlFor('home');

return $response
  ->withHeader('Location', $location)
  ->withStatus(301);

PS: For redirects you can also use the $app->redirect(...) helper method.

Read more: Redirect helper

1 Like

@odan this is great, thank you. Could you consider to add your reply to the official documentation at: Response - Slim Framework ?

And also one more point/question:
How to redirect both versions with or without ending backslash by one route?

$app->get('/old-url', function ...
$app->get('/old-url/', function ...

For a simple route I think the easiest way would be to use the redirect helper:

// Relative paths
$app->redirect('/old-path', 'new-path');
$app->redirect('/old-path/', '../new-path');

Thank you @odan I was just curious if Slim provides building of routes with using regular expressions.
Something like this:

$app->get('/old-url[/?]', function ...

or

$app->redirect('/old-path[/?]', 'new-path');

I am used to that from Symfony framework, something like:

 @Route("/{articleId}/{articleAlias}/",
     *     name="redirect_article_alias",
     *     methods={"GET"},
     *     requirements={"articleId": "[0-9]+?", "articleAlias": "[a-zA-Z0-9\-\_]+?"}
     *     )

That’s all :slightly_smiling_face:

Yes, you can also use route placeholders in Slim.