Skip to content
intermediate Phase 32 · Advanced XML

menu.xml — Admin Menu Structure

Admin menu items, ACL permissions, custom menu entries, and menu configuration.

30m
0 problems
Topic Progress 0%

menu.xml Structure

menu.xml defines the admin navigation menu structure.

Basic menu.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
        <!-- Add under existing top-level item -->
        <add id="Vendor_Blog::blog" title="Blog" module="Vendor_Blog"
             sortOrder="80" resource="Vendor_Blog::blog"/>
        
        <!-- Add child items -->
        <add id="Vendor_Blog::blog_posts" title="Posts" module="Vendor_Blog"
             sortOrder="10" parent="Vendor_Blog::blog" resource="Vendor_Blog::blog_posts"/>
        
        <add id="Vendor_Blog::blog_categories" title="Categories" module="Vendor_Blog"
             sortOrder="20" parent="Vendor_Blog::blog" resource="Vendor_Blog::blog_categories"/>
        
        <add id="Vendor_Blog::blog_settings" title="Settings" module="Vendor_Blog"
             sortOrder="30" parent="Vendor_Blog::blog" resource="Vendor_Blog::blog_settings"/>
    </menu>
</config>

Menu attributes:

Attribute Description
id Unique menu item identifier
title Display text
module Module that owns this item
sortOrder Display order within parent
parent Parent menu item ID
resource ACL resource for visibility
action URL action path
titleTranslated Translation key (optional)

Menu hierarchy:

Content (Magento_Cms)
├── Pages
├── Blocks
└── Blog (Vendor_Blog) ← custom
    ├── Posts
    ├── Categories
    └── Settings

ACL Integration

Menu items are only visible if the user has the required ACL resource.

ACL-controlled menu:

<add id="Vendor_Blog::blog" title="Blog" module="Vendor_Blog"
     sortOrder="80" resource="Vendor_Blog::blog"/>

Without ACL (visible to all):

<!-- No resource attribute = always visible -->
<add id="Vendor_Blog::blog" title="Blog" module="Vendor_Blog"
     sortOrder="80"/>

ACL hierarchy:

<!-- If user has Vendor_Blog::blog, they see all children -->
<add id="Vendor_Blog::blog" resource="Vendor_Blog::blog"/>
<add id="Vendor_Blog::posts" parent="Vendor_Blog::blog" resource="Vendor_Blog::blog_posts"/>
<add id="Vendor_Blog::settings" parent="Vendor_Blog::blog" resource="Vendor_Blog::blog_settings"/>

Restricting menu items:

<!-- Only admin users with catalog permission see this -->
<add id="Vendor_Blog::import" title="Import" module="Vendor_Blog"
     parent="Magento_Catalog::catalog" resource="Magento_Catalog::catalog_products"/>

Debugging menu visibility:

# Check admin role permissions
php bin/magento admin:roles:list

# Verify ACL resources
grep -r "Vendor_Blog::" app/code/Vendor/Blog/etc/acl.xml

# Check menu registration
php bin/magento dev:module:list --enabled | grep Vendor_Blog

Menu Positioning and Icons

Control menu item positioning and visual appearance.

Sort order examples:

<!-- Content section approximate sort orders -->
Magento_Cms::cms → 20
Magento_Catalog::catalog → 30
Vendor_Blog::blog → 80 (appears after catalog)

Adding to existing sections:

<!-- Add under Sales -->
<add id="Vendor_Blog::sales_blog" title="Blog Orders" module="Vendor_Blog"
     parent="Magento_Sales::sales" sortOrder="50" resource="Vendor_Blog::blog"/>

<!-- Add under Marketing -->
<add id="Vendor_Blog::marketing" title="Blog Marketing" module="Vendor_Blog"
     parent="Magento_Marketing::marketing" sortOrder="60"/>

Custom action URLs:

<add id="Vendor_Blog::blog_posts" title="Posts" module="Vendor_Blog"
     parent="Vendor_Blog::blog" sortOrder="10"
     action="vendor_blog/post/index" resource="Vendor_Blog::blog_posts"/>

Menu icons (CSS):

<!-- Add icon via CSS class -->
<add id="Vendor_Blog::blog" title="Blog" module="Vendor_Blog"
     sortOrder="80" resource="Vendor_Blog::blog">
    <class>vendor-blog-icon</class>
</add>
/* In admin CSS */
.vendor-blog-icon::before {
    content: '\e000'; /* Custom icon */
    font-family: 'icons';
}

Removing menu items:

<!-- Remove existing menu item -->
<remove id="Magento_Cms::cms_pages"/>

<!-- Remove entire section -->
<remove id="Magento_Backend::marketing"/>

Dynamic Menu Items

Create menu items dynamically based on configuration or data.

Remove and re-add pattern:

<!-- Remove default, add custom -->
<remove id="Magento_Catalog::catalog_products"/>

<add id="Vendor_Module::catalog_products" title="Products" module="Vendor_Module"
     parent="Magento_Catalog::catalog" sortOrder="10"
     action="catalog/product" resource="Magento_Catalog::catalog_products"/>

Menu with external link:

<add id="Vendor_Blog::docs" title="Documentation" module="Vendor_Blog"
     sortOrder="100" resource="Magento_Backend::admin"
     action="https://docs.example.com"/>

Module menu integration:

<!-- Your module adds to third-party menu -->
<add id="Vendor_Extension::thirdparty_section" title="Extensions" module="Vendor_Extension"
     parent="ThirdParty_Module::menu" sortOrder="100"/>

Menu debugging:

# View complete menu tree
php bin/magento dev:module:list

# Check if menu item is registered
grep -r "Vendor_Blog::" app/code/Vendor/Blog/etc/menu.xml

# Flush admin cache
php bin/magento cache:clean config

Quiz

1. What XML file defines the admin menu?

Question 1 options

2. What attribute controls menu item visibility via permissions?

Question 2 options

3. How do you create a child menu item?

Question 3 options

4. How do you remove an existing menu item?

Question 4 options

Flashcards

Question

What file defines admin menu items?

Answer

menu.xml

Question

How do you make a menu item child of another?

Answer

Set parent="parent_item_id" attribute

Question

What controls menu item visibility?

Answer

resource attribute referencing ACL resources

Question

How do you remove a menu item?

Answer

<remove id="item_id"/>

Question

What does sortOrder control?

Answer

Display order within the parent menu section

Revision Notes

Key Takeaways

  • 1. menu.xml defines admin navigation with add and remove elements
  • 2. Each item needs id, title, module, and optionally parent/resource
  • 3. ACL resources control which users can see menu items
  • 4. sortOrder determines display order within parent sections
  • 5. Use <remove> to eliminate existing menu items
  • 6. Menu items can link to external URLs via action attribute

Interview Tips

  • Explain how to add custom menu items
  • Describe ACL-based menu visibility
  • Know how to remove or replace existing menu items
  • Discuss menu positioning with sortOrder

Cheat Sheet

menu.xml Cheat Sheet

Add item:

<add id="Vendor_Module::section" title="Title" module="Vendor_Module"
     parent="Magento_Backend::admin" sortOrder="100"
     resource="Vendor_Module::resource"/>

Remove item:

<remove id="Magento_Cms::cms_pages"/>

Attributes:

  • id: Unique identifier
  • title: Display text
  • parent: Parent menu item ID
  • sortOrder: Display order
  • resource: ACL resource
  • action: URL action path

ACL: resource controls visibility