Skip to main content
Menus are built from a navigation registry that the core fills at boot. A plugin adds its own entries in boot(), so its pages appear alongside the built-in ones.

Add an item

src/Plugin.php
Registry::item(string $target, Item $item) appends to a section. If an item with the same URL is already registered in that section, the new one is ignored, so booting twice can’t duplicate an entry.

Item reference

Icon formats

Sections

Put an integration’s configuration under admin.settings.common, and a feature that users interact with under admin.settings.features. Use the app sections for pages your users open every day.
Creating a section is possible too, though it only shows up where a template renders it:
The third argument makes the group collapsible.

Show items conditionally

Registration happens once per request, so read your feature flag in boot():
Keep the admin entry visible even when the feature is off, or administrators can’t find the switch that turns it back on.

Highlighting the current page

Templates decide which entry is active from the active_menu variable, so set it to the same URL you registered:
Admin settings pages use {% set active_menu = 'settings' %} instead, and pages under Plugins use {% set active_menu = '/admin/plugins' %}.

Translating labels

Labels pass through gettext with the nav context, and the templates translate them again at render time. Always wrap them:
Ship the catalogs with your plugin, as described in Localization.