A number of popular API functions have been removed in Drupal 8 including drupal_set_title(). This function allows you to change the title that is displayed on the page and in the title bar. It accepts two parameters — the string for the title ($title) and an integer ($output) represented by either of two constants, CHECK_PLAIN (0) or PASS_THROUGH (-1):

The default is CHECK_PLAIN which tells Drupal to sanitize the text and make sure it does not contain dangerous code. The PASS_THROUGH flag indicates that the string has already been sanitized.

drupal_set_title('My new page title');
drupal_set_title('New page title 2', PASS_THROUGH);

What have we got as a replacement for this handy function in Drupal 8? It turns out we have more than one way.


This is the place to set the page title, and it is done differently depending on whether it is static or dynamic. Let us look at examples from the Taxonomy module in core.


In taxonomy.routing.yml the page title is set with the _title key for the route given a value of 'Add vocabulary':

  path: '/admin/structure/taxonomy/add'
    _entity_form: 'taxonomy_vocabulary'
    _title: 'Add vocabulary'
    _entity_create_access: 'taxonomy_vocabulary'


Still looking at the same configuration file, when editing a vocabulary, the page title is set to the current one. The page title is set with the _title_callback key.

  path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}'
    _entity_form: 'taxonomy_vocabulary.default'
    _title_callback: '\Drupal\taxonomy\Controller\TaxonomyController::vocabularyTitle'
    _entity_access: 'taxonomy_vocabulary.update'

Then the vocabulary label is returned as a render array from the controller method:

// src/Controller/TaxonomyController.php

public function vocabularyTitle(VocabularyInterface $taxonomy_vocabulary) {
    return ['#markup' => $taxonomy_vocabulary->label(), '#allowed_tags' => Xss::getHtmlTagList()];

Render array

If you want to override a page title where you have a render array, then you can set the #title or title key as follows:

  $build['#title'] = 'The new page title';
// or
  $build['title'][0]['#context']['value'] = 'The new page title';


The related drupal_get_title() has also been removed. There is a title_resolver service with a getTitle() method which takes two parameters — the current request and route.

$request = \Drupal::request();
$route = \Drupal::routeMatch()->getRouteObject();

$title = \Drupal::service('title_resolver')->getTitle($request, $route);


Initially, the new architecture may look more difficult than older versions of Drupal. Once the initial learning hurdle has been crossed it becomes fairly easier to appreciate the new options at one's disposal. Changing a page title is a good example.