The core navigation module now includes a section named content_top, which sits right above the content section. While the content section is controlled editorially via config entities, the content_top section is controlled programmatically by module developers who wish to provide integrations for this area of the navigation. Examples include environment indicator, workspaces, and Umami. To take advantage of this new content_top section, module developers can leverage two new hooks.
hook_navigation_content_top
To add content to the content_top region, implement hook_navigation_content_top. Return an array of render arrays, keyed by a unique name, as needed for your integration:
function my_module_navigation_content_top(): array { return [ 'my_module_foo' => [ '#markup' => 'foo', ], 'my_module_bar' => [ '#markup' => 'bar', ], ]; }
hook_navigation_content_top_alter
To alter the contents of the content_top region that have been provided by other modules, implement hook_navigation_content_top_alter. The hook is provided with a render array by reference for all the integrations that have been added by hook_navigation_content_top implementations.
function my_module_navigation_content_top_alter(&$content_top): void { unset($content_top['navigation_foo']); $content_top['navigation_bar']['#markup'] = 'new bar'; }
Drupal 11.1 and later support OOP/attribute-based hooks as well.
my_module/src/Hook/MyModuleNavigationHooks.php
<?php namespace Drupal\my_module\Hook; use Drupal\Core\Hook\Attribute\Hook; class MyModuleNavigationHooks { /** * Provide content for Navigation content_top section. */ #[Hook('navigation_content_top')] public function navigationContentTop(): array { return [ 'my_module_foo' => [ '#markup' => 'foo', ], 'my_module_bar' => [ '#markup' => 'bar', ], ]; } /** * Alter the content_top section of the Navigation module. */ #[Hook('navigation_content_top_alter')] public function navigationContentTopAlter(array &$content_top): void { unset($content_top['my_module_foo']); $content_top['my_module_bar']['#markup'] = 'updated bar'; } }
Adjust the render array to your needs as above. This is a basic example, but it can be as complex as you like. As always, be sure to cover your cacheability metadata where applicable.