If you implement the hook_menu_links_discovered_alter() hook in Drupal 8.3 you have access to change the links with a code like this:

 * Implements hook_menu_links_discovered_alter().
function onlyone_menu_links_discovered_alter(&$links) {
    $links['node.add.article']['title'] = t('New name');

This code comes from the issue Improve the Add content page for the Allow a content type only once (Only One) module. But starting from Drupal 8.4 the same code gives an error like this:

Notice: Undefined index: node.add.article in onlyone_menu_links_discovered_alter()

I searched inside the Drupal change records but I don't find anything talking about this change.

Now in Drupal 8.4 how you can change a link title?

1 Answer 1


There are several things I notice here:

  1. An undefined index error shouldn't result just from this code - you're not referencing the array index; just setting it. Does the actual code have a more complex expression which references $links['node.add.article']?

  2. This is not quite correct for this hook (and the linked issue is for 7.x, so it can't be compared). The hook documentation says that the menu item must be an associative array - it should be altered with $links['node.add.page']['title'] = '...';

  3. The array key is not guaranteed to be fixed:

Since the machine name may be arbitrary, you should never write code that assumes it is identical to the route name.

Therefore you should probably iterate and identify the menu link by the route name instead.

  1. From what I can tell, core doesn't (and never did) define menu links for the node.add.{type} routes. The links on the /node/add page are dynamically generated, and don't actually show up in any menu.

So it doesn't seem to be possible to alter the links on the /node/add page by altering the menu. As you can see from the function below, these links are actually generated in a template preprocessor:

function template_preprocess_node_add_list(&$variables) {
  $variables['types'] = [];
  if (!empty($variables['content'])) {
    foreach ($variables['content'] as $type) {
      $variables['types'][$type->id()] = [
        'type' => $type->id(),
        'add_link' => \Drupal::l($type->label(), new Url('node.add', ['node_type' => $type->id()])),
        'description' => [
          '#markup' => $type->getDescription(),

The only way to modify the link text would be to replace the links in another preprocess function.

Edit: This other answer actually explains how to do that in detail: How to modify the link titles shown in /node/add page?

  • 1
    Thanks for your answer. Its weird I see now that the commit for tje 8.x version doesn't appears 8n the issue but is here drupalcode.org/onlyone/commit/?id=dc861a2 and I edit the correct code in the question. If you want to see the issue install the module in Drupal 8.3 and Drupal 8.4 and then select one Content Type to have only one node. Nov 25, 2017 at 2:57
  • 1
    I agree with point 4., core doesn't define these menu links. My guess is that they are defined here: drupal.org/project/admin_menu
    – 4uk4
    Nov 25, 2017 at 8:35
  • 1
    Indeed, there are several contrib modules that define these; admin_toolbar is another one. Nov 25, 2017 at 9:14
  • 1
    @ChristophBurschka Very funny this to me. I just see that is Admin Toolbar Extra Tools the module that creates this links, and as I usually have this module installed I never see before the problem :-O Nov 27, 2017 at 18:25
  • @ChristophBurschka I don't know if I need to edit now the Question. What do you think? Nov 27, 2017 at 18:25

Your Answer

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

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