Third & GroveThird & Grove
Sep 15, 2016 - Josh Fremer

Redirecting Node Pages in Drupal 8

 

Adding a redirect for node pages in Drupal is easy, but requires a few steps.

First, your module must have a my_module.services.yml file in the module directory. This file will be loaded automatically. Include the following entry:

services:
  my_module.redirectmycontenttype:
    class: Drupal\my_module\EventSubscriber\MyModuleRedirectSubscriber
    tags:
      - { name: event_subscriber }

 

Now create a folder in your module directory named src/EventSubscriber (create the src directory if it doesn't exist). In it, create a file named MyModuleRedirectSubscriber.php. You'll need to add several includes as well as a getSubscribedEvents() method and a callback for the redirect action:

/**
 * @file
 * Contains \Drupal\my_module\EventSubscriber\MyModuleRedirectSubscriber
 */
 
namespace Drupal\my_module\EventSubscriber;
 
use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
 
class MyModuleRedirectSubscriber implements EventSubscriberInterface {
 
  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // This announces which events you want to subscribe to.
    // We only need the request event for this example.  Pass
    // this an array of method names
    return([
      KernelEvents::REQUEST => [
        ['redirectMyContentTypeNode'],
      ]
    ]);
  }
 
  /**
   * Redirect requests for my_content_type node detail pages to node/123.
   *
   * @param GetResponseEvent $event
   * @return void
   */
  public function redirectMyContentTypeNode(GetResponseEvent $event) {
    $request = $event->getRequest();
 
    // This is necessary because this also gets called on
    // node sub-tabs such as "edit", "revisions", etc.  This
    // prevents those pages from redirected.
    if ($request->attributes->get('_route') !== 'entity.node.canonical') {
      return;
    }
 
    // Only redirect a certain content type.
    if ($request->attributes->get('node')->getType() !== 'my_content_type') {
      return;
    }
 
    // This is where you set the destination.
    $redirect_url = Url::fromUri('entity:node/123');
    $response = new RedirectResponse($redirect_url->toString(), 301);
    $event->setResponse($response);
  }
 
}

 

That's all there is to it! Now any visitors to nodes of type my_content_type will be redirected to node/123. The node object you have access to here is fully-populated, so you can do things like redirect based on field values.