I created a custom content entity type dog using drush generate entity:content.

When I go to www.example.com/dog/add, the page title (the one in the <title> tag, not the <h1> tag) is "Add dog". I want to change this to "Send a dog to outer space (and bring him back safely)".

It seems there is no place to set the title in the entity annotations, so I attempted to add an event subscriber:


class DogRouteSubscriber extends RouteSubscriberBase {

   * {@inheritdoc}
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.dog.add_form')) {
      $route->setDefault('_title', 'Send a dog to outer space (and bring him back safely)');


    class: Drupal\dog\Routing\DogRouteSubscriber
      - { name: event_subscriber }

I am using $route->setDefault('_title', 'Send a dog to outer space (and bring him back safely)' based on code in this blog post, but even after rebuilding the cache, the page title isn't changed.

So: Where do I alter (or set) the entity add form's page title?

Similar but different questions:

2 Answers 2


If your entity uses DefaultHtmlRouteProvider as route_provider handler then it sets a title callback which has a higher priority than the static title. So you would need to remove this default in alterRoutes().

However, if this is your own entity, a more straightforward approach would be to edit the entity annotations and replace the route_provider handler with your own class , which extends DefaultHtmlRouteProvider and overrides the method getAddPageRoute():

  protected function getAddPageRoute(EntityTypeInterface $entity_type) {
    if ($entity_type->hasLinkTemplate('add-page') && $entity_type->getKey('bundle')) {
      $route = new Route($entity_type->getLinkTemplate('add-page'));
      $route->setDefault('_controller', EntityController::class . '::addPage');
      $route->setDefault('_title_callback', EntityController::class . '::addTitle');
      $route->setDefault('entity_type_id', $entity_type->id());
      $route->setRequirement('_entity_create_any_access', $entity_type->id());

      return $route;

Or keep the dynamic controller method and return the static text from there.


Wow, this turned out to be way more complex than I thought.

In addition to the DogRouteSubscriber shown in the original question, I had to override getAddFormRoute (because the basic entity type generated with drush generate does not have an add-page route) with my own DogHtmlRouteProvider class (as described in 4uk4's answer):

class DogHtmlRouteProvider extends DefaultHtmlRouteProvider {

   * Gets the add-form route.
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *   The entity type.
   * @return \Symfony\Component\Routing\Route|null
   *   The generated route, if available.
  protected function getAddFormRoute(EntityTypeInterface $entity_type) {
    if ($entity_type->hasLinkTemplate('add-form')) {
      $entity_type_id = $entity_type->id();
      $route = new Route($entity_type->getLinkTemplate('add-form'));
      // Use the add form handler, if available, otherwise default.
      $operation = 'default';
      if ($entity_type->getFormClass('add')) {
        $operation = 'add';
        '_entity_form' => "{$entity_type_id}.{$operation}",
        'entity_type_id' => $entity_type_id,

        ->setRequirement('_entity_create_access', $entity_type_id);

      return $route;

Here, I removed the line $route->setDefault('_title_callback', EntityController::class . '::addTitle'); I did not override this with another method because _title_callback apparently only accepts a method on a descendant of EntityController, and my module doesn't have such a controller.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.