By default, the admin menu is built by the AdminMenuBuilder class. However, you can easily customize it by creating your own menu builder that implements the AdminMenuBuilderInterface.
To create a custom menu builder, you need to create a class that implements Aropixel\AdminBundle\Component\Menu\Builder\AdminMenuBuilderInterface. You should also use Symfony's attributes to tag it and alias it so it replaces the default builder.
The AdminMenuBuilderInterface requires you to implement a buildMenu() method that returns an array of Menu objects.
Here is an example of a custom menu builder:
<?php
namespace App\Component\AdminMenu;
use Aropixel\AdminBundle\Component\Menu\Builder\AdminMenuBuilderInterface;
use Aropixel\AdminBundle\Component\Menu\Model\Link;
use Aropixel\AdminBundle\Component\Menu\Model\Menu;
use Aropixel\AdminBundle\Component\Menu\Model\SubMenu;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\AsAlias;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
#[AutoconfigureTag('admin_menu_builder')]
#[AsAlias(id: AdminMenuBuilderInterface::class)]
class CustomAdminMenuBuilder implements AdminMenuBuilderInterface
{
public function __construct(
private readonly Security $security,
) {
}
public function buildMenu(): array
{
$additionalMenus = [];
// Menu accessible to ROLE_CONTENT_EDITOR and above
if ($this->security->isGranted('ROLE_CONTENT_EDITOR')) {
$additionalMenus[] = $this->buildContentMenu();
}
// Menus reserved for ROLE_SUPER_ADMIN
if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
$additionalMenus[] = $this->buildAdminMenu();
}
return $additionalMenus;
}
private function buildContentMenu(): Menu
{
$menu = new Menu('content', 'Content');
$menu->addItem(new Link('Articles', 'admin_article_index'));
// Add a sub-menu
$subMenu = new SubMenu('Legal', [], 'legal');
$subMenu->addItem(new Link('Terms of Service', 'admin_legals_tos'));
$subMenu->addItem(new Link('Privacy Policy', 'admin_legals_privacy'));
$menu->addItem($subMenu);
return $menu;
}
private function buildAdminMenu(): Menu
{
$menu = new Menu('admin', 'Administration');
$menu->addItem(new Link('Users', 'aropixel_admin_user_index'));
return $menu;
}
}There are three main classes you will use to build your menu:
A Menu represents a top-level category in the admin sidebar.
__construct(string $id, string $label)addItem(ItemInterface $item): Adds a link or a sub-menu.
A Link represents a single menu item that points to a route.
__construct(string $label, string $routeName, array $routeParameters = [], array $properties = [], string $id = null)- The
propertiesarray carries arbitrary per-item data, read back withgetProperty('key')— e.g.['target' => '_blank'].
Menu-item icons. The shipped fullscreen menu renders labels only — it displays no per-item icon, so a
['icon' => …]property has no visible effect with the default templates. (The bundle's own builders no longer set one.) If you want icons, override the menu templates —@AropixelAdmin/Menu/link.html.twigand@AropixelAdmin/Menu/submenu.html.twig— and render the property with the icon system:{{ ux_icon('lucide:file-text') }}. See Icons — the admin uses ux-icons with the Lucide set, not an icon font.
A SubMenu allows you to group multiple links under a collapsible parent.
__construct(string $label, array $properties, string $id = null)addItem(ItemInterface $item): Adds a link to the sub-menu.setDefaultChild(Link $defaultChild): Sets the link to be used if the sub-menu itself is clicked.
The Quick Menu provides shortcuts that are typically displayed on the dashboard or in the fullscreen menu. Like the main menu, it can be customized by implementing the QuickMenuBuilderInterface.
To create a custom quick menu builder, implement Aropixel\AdminBundle\Component\Menu\Builder\QuickMenuBuilderInterface. Use Symfony attributes to tag and alias it.
Important: The default Twig template for the quick menu uses the array keys (1 to 5) to apply specific CSS classes and colors. If you want to maintain the original styling, ensure your return array uses these keys.
<?php
namespace App\Component\AdminMenu;
use Aropixel\AdminBundle\Component\Menu\Builder\QuickMenuBuilderInterface;
use Aropixel\AdminBundle\Component\Menu\Model\Link;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\AsAlias;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\Routing\RouterInterface;
#[AutoconfigureTag('admin_menu_builder')]
#[AutoconfigureTag('quick_menu_builder')]
#[AsAlias(id: QuickMenuBuilderInterface::class)]
class CustomQuickMenuBuilder implements QuickMenuBuilderInterface
{
public function __construct(
private readonly RouterInterface $router,
private readonly Security $security,
) {
}
public function buildMenu(): array
{
$quickMenu = [];
// Key 1: Light Blue background
if ($this->routeExists('app_custom_route')) {
$quickMenu[1] = new Link('Custom', 'app_custom_route');
}
// Key 2: Orange background
if ($this->security->isGranted('ROLE_ADMIN')) {
$quickMenu[2] = new Link('Admin', 'admin_dashboard');
}
return $quickMenu;
}
private function routeExists(string $name): bool
{
return !(null === $this->router->getRouteCollection()->get($name));
}
}