Skip to main content
The bundle supports two distinct levels of collapse behaviour, both driven by flags on the Menu entity and rendered with Bootstrap 5 markup.

Top-level collapse (collapsible)

When the Collapsible flag is enabled on a menu, the entire menu is wrapped in a block with a toggle button. Clicking the button expands or collapses the full <ul> tree. The generated markup looks like this:
<div class="dashboard-menu-collapsible">
    <button
        type="button"
        class="dashboard-menu-toggle btn btn-link ..."
        data-bs-toggle="collapse"
        data-bs-target="#dashboard-menu-sidebar"
        aria-expanded="true"
        aria-controls="dashboard-menu-sidebar"
    >
        <span>Sidebar</span>
        <span class="dashboard-menu-toggle-icon" aria-hidden="true"></span>
    </button>

    <div id="dashboard-menu-sidebar" class="collapse show">
        <ul class="dashboard-menu sidebar dashboard-menu-tree">
            <!-- items -->
        </ul>
    </div>
</div>
  • The toggle button label is the menu’s name (or code as fallback).
  • The dashboard-menu-toggle-icon span is a hook for a CSS chevron.
  • class="collapse show" when expanded; class="collapse" when collapsed.
Bootstrap’s collapse JavaScript must be loaded on the page for the toggle to work. The bundle only generates the markup and data attributes — it does not bundle Bootstrap JS.

Default state (collapsible_expanded)

The Collapsible expanded flag controls whether the menu starts open or closed:
collapsible_expandedInitial state
true (default)Menu is open on page load
falseMenu is collapsed on page load

Nested item collapse (nested_collapsible)

When Nested collapsible is enabled, each item that has children gets its own toggle button beside the label. Children are rendered inside a Bootstrap collapse <div>.
<li>
    <a href="/reports">Reports</a>
    <button
        type="button"
        class="btn btn-link btn-sm p-0 ms-1 menu-nested-toggle"
        data-bs-toggle="collapse"
        data-bs-target="#sidebar-item-42"
        aria-expanded="true"
        aria-controls="sidebar-item-42"
    >
        <span class="menu-nested-toggle-icon" aria-hidden="true"><!-- chevron SVG --></span>
    </button>

    <div id="sidebar-item-42" class="collapse show">
        <ul>
            <!-- child items -->
        </ul>
    </div>
</li>
Branches that contain the current route always start expanded (class="collapse show"), regardless of the default expanded state.

Section items and nested collapse

Items with type Section (a non-clickable group header) also get a toggle button when nested_collapsible is enabled. The chevron is placed after the section label:
<span class="d-flex align-items-center flex-nowrap">
    <span class="navigation-header">Reports</span>
    <button ... data-bs-toggle="collapse" ...>
        <span class="menu-nested-toggle-icon" aria-hidden="true">...</span>
    </button>
</span>

Chevron styling

Both toggle types provide a <span> element for a CSS-driven chevron. Add this CSS (or adapt it to your design system):
/* Top-level menu toggle */
.dashboard-menu-toggle-icon::after {
    content: "\25BE"; /* ▾ */
}
.dashboard-menu-toggle[aria-expanded="false"] .dashboard-menu-toggle-icon::after {
    content: "\25B8"; /* ▸ */
}

/* Nested item toggle */
.menu-nested-toggle-icon::after {
    content: "\25BE";
}
.menu-nested-toggle[aria-expanded="false"] .menu-nested-toggle-icon::after {
    content: "\25B8";
}
The bundle inlines a small SVG chevron inside .menu-nested-toggle-icon by default. If you prefer a CSS ::after approach, override the template or remove the SVG via CSS (display: none) and use the ::after pseudo-element instead.

Configuring collapse options

All three flags are set on the Menu entity in the dashboard (gear icon → Configuration tab). There is no global YAML equivalent — the settings are per-menu.
FlagEffect
collapsibleWrap menu in a toggle block
collapsible_expandedStart expanded (true) or collapsed (false)
nested_collapsibleAdd per-item toggles for items with children
These values are also exposed in the menuConfig array returned by dashboard_menu_config(), so custom templates can read them:
{% set menuConfig = dashboard_menu_config('sidebar') %}
{% if menuConfig.collapsible %}
    {# wrap in your own collapsible markup #}
{% endif %}