dashboard_menu and dashboard_menu_item. Understanding their fields is the foundation for working with the bundle programmatically or through the dashboard.
Menu
Menu is the container that groups a set of items under a unique code. A single code (e.g. sidebar) can have several Menu rows, each with a different context, to serve different tenants or configurations.
Unique constraint
The pair(code, attributes_key) has a unique constraint on the table. attributes_key is the result of Menu::canonicalContextKey() — a sorted, JSON-encoded version of the context array. An empty string represents “no context” (the fallback row for that code).
Two
Menu rows with the same code but different contexts are valid. Two rows with the same code and the same context (or both with no context) will fail the unique constraint.Identity and classification fields
Short identifier for this menu, e.g.
sidebar or topbar. Combined with context to identify a unique variant.Human-readable label shown in the dashboard UI.
Optional JSON key-value map that distinguishes this menu from others sharing the same code (e.g.
{"partnerId": 1}). null or [] means this row is the fallback for that code.Optional icon identifier for the menu container (e.g.
heroicons:bars-3).When
true, the menu is a “base” menu whose code cannot be changed after creation.CSS class overrides
Each field overrides the corresponding global config value when set. Leavenull to fall back to config defaults.
CSS class for the root
<ul> element (e.g. nav flex-column).Optional
id attribute for the root <ul> element.CSS class for each
<li> element (e.g. nav-item).CSS class for each
<a> element (e.g. nav-link).CSS class for nested
<ul> elements (e.g. nav flex-column ms-2).CSS class for the
<span> wrapping a section item’s label (e.g. navigation-header).Class added to
<a> when its route matches the current request (e.g. active).Class added to
<li> when the current route is within that branch (e.g. active-branch).Class added to
<li> when the item has children.Class added to
<li> when the item’s children block is expanded.Class added to
<li> when the item’s children block is collapsed.Behaviour flags
Service ID of the
MenuPermissionCheckerInterface implementation to use for this menu. null defaults to allow-all.Maximum depth to render.
null = unlimited. 1 = root items only, 2 = root + one level of children, etc.When
true, the entire menu is wrapped in a collapsible toggle block.When
collapsible is true, controls whether the block starts open (true) or closed (false).When
true, each item that has children renders an expand/collapse control.When
nestedCollapsible is true, controls whether section-type items also render a collapse toggle. Defaults to true for backwards compatibility.Cascade delete
Theitems collection is mapped with cascade: ['persist', 'remove'] and orphanRemoval: true. Deleting a Menu automatically removes all of its MenuItem rows.
MenuItem
MenuItem represents a single entry in the tree. It implements TranslatableInterface so its label can be stored in multiple locales.
Label and translations
Default/fallback label. Used when no translation exists for the current locale.
null is valid for divider items that have no label.Per-locale label overrides stored as JSON (e.g.
{"en": "Home", "es": "Inicio"}). The repository resolves the correct label at load time via getLabelForLocale(locale).MenuItem implements TranslatableInterface, which requires:
translations[$locale] if present, otherwise label.
Item type
Controls how the item is rendered.
link— a clickable<a>element (default)section— a non-linked label used as a group headerdivider— a horizontal rule with no label
Link fields
How the URL is generated.
null when the item has children and acts as a parent node without its own destination.Symfony route name when
linkType = route.Route parameters as a JSON map (e.g.
{"tab": "configuration"}). Missing path parameters are filled from the current request.Full URL when
linkType = external.When
true, the rendered link gets target="_blank" rel="noopener noreferrer".Tree positioning
Parent item.
null means this is a root-level item. Cascade delete is set on the column so removing a parent removes all its descendants.Sort order within the same parent. Items are ordered
ASC by position. Default is 0.Other fields
Icon identifier passed to Symfony UX Icons (e.g.
heroicons:home, bootstrap:house). Resolved through the configured icon_library_prefix_map before rendering.Arbitrary string passed to the menu’s
MenuPermissionCheckerInterface implementation. How it is interpreted depends on your checker. See Permissions.Related concepts
Context resolution
How multiple Menu rows for the same code are resolved at render time.
Permissions
How permissionKey and permission checkers control item visibility.
Tree structure
How the flat list of items is assembled into a nested tree.