Route Subscribers
When to Use
Use when you need to alter existing routes from core or contrib modules. Do NOT use to create routes - use
route_callbacksor static YAML instead.
Decision
| Situation | Choose | Why |
|---|---|---|
| Alter existing route properties | RouteSubscriber with alterRoutes() |
Modify path, requirements, defaults, options |
| Change route access control | Alter requirements in alterRoutes() |
Add/remove/modify access checks |
| Redirect route to different controller | Alter _controller default |
Override behavior without patching |
| Adjust route weight/priority | getSubscribedEvents() with priority |
Control order of route processing |
Pattern
// src/Routing/RouteSubscriber.php
namespace Drupal\my_module\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
class RouteSubscriber extends RouteSubscriberBase {
protected function alterRoutes(RouteCollection $collection) {
// Alter user login route
if ($route = $collection->get('user.login')) {
$route->setPath('/custom-login');
$route->setDefault('_title', 'Custom Login');
}
// Change access requirements
if ($route = $collection->get('my_module.page')) {
$route->setRequirement('_permission', 'new permission');
}
}
// Control subscriber weight/priority
public static function getSubscribedEvents(): array {
$events = parent::getSubscribedEvents();
// Run after other subscribers (higher number = later)
$events[RoutingEvents::ALTER] = ['onAlterRoutes', -200];
return $events;
}
}
# my_module.services.yml
services:
my_module.route_subscriber:
class: Drupal\my_module\Routing\RouteSubscriber
tags:
- { name: event_subscriber }
Reference: core/lib/Drupal/Core/Routing/RouteSubscriberBase.php
Common Mistakes
- Wrong: Using RouteSubscriber to create routes → Right: Use
route_callbacksfor new routes - Wrong: Not checking if route exists before altering → Right: Always check
if ($route = $collection->get(...)) - Wrong: Forgetting to register service with tag → Right: Add
event_subscribertag in services.yml - Wrong: Wrong event priority causing conflicts → Right: Adjust priority number to control order
- Wrong: Altering routes without clearing cache → Right: Run
drush crafter changes