I wanted to remove all menu items from top menu and fill in with my categories and subcategories and make it point to different pages that I create. should I edit topmenu.phtml file?


You need to create a new module that disables the plugin that adds the categories to the top menu and create a new plugin that adds your custom links to it.
Let's call the module StackExchange_Menu.

you will need the following files:

app/code/StackExchange/Menu/registration.php - the registration file



app/code/StackExchange/Menu/etc/module.xml - the module declaration file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="StackExchange_Menu" setup_version="1.0.0">
            <module name="Magento_Catalog"/>

app/code/StackExchange/Menu/etc/di.xml - the module di file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Theme\Block\Html\Topmenu">
        <plugin name="catalogTopmenu" disabled="true" /> <!-- disable the plugin that adds the categories -->
        <plugin name="stackexchange-menu" type="StackExchange\Menu\Plugin\Menu" /> <!-- declare your own plugin -->

app/code/StackExchange/Menu/Plugin/Menu.php - the actual plugin where you can add your menu items.

namespace StackExchange\Menu\Plugin;

use Magento\Framework\Data\Tree\NodeFactory;

class Menu
     * @var NodeFactory
    protected $nodeFactory;

    public function __construct(
        NodeFactory $nodeFactory
    ) {
        $this->nodeFactory = $nodeFactory;

    public function beforeGetHtml(
        \Magento\Theme\Block\Html\Topmenu $subject,
        $outermostClass = '',
        $childrenWrapClass = '',
        $limit = 0
    ) {
        $menu = $subject->getMenu();
        //here is how you can create a menu item.  
        $node = $this->nodeFactory->create(
                    'data' => [
                    'name' => __('Label goes here'),
                    'id' => 'some-unique-id-here',
                    'url' => 'http://www.example.com/',
                    'has_active' => false,
                    'is_active' => false // (expression to determine if menu item is selected or not)
                'idField' => 'id',
                'tree' => $menu->getTree()

        //do the above as many times as you need.  
        //if you want to add a sumbmenu item to a menu item, create a node called `$subNode` in the same way as above and instead of calling $menu->addChild($node); call $node->addChild($subNode);  where $node is the parnet node

When you are done, run in console bin/magento setup:upgrade.
Note: The code above is not tested. Watch out for syntax error.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.