As we know Magento 2 does not include features like adding extra(home, blog) links to main navigation menu. In this blog post we will discuss how to add non category links to navigation menu in Magento 2. In this we will use Magento 2 Observer page_block_html_topmenu_gethtml_before to add new link to menu.

Lets consider module with Namespace is Hiddentechies and Module Name is NavLinks. Lets list down all the files require for this extension.

– registration.php
– composer.json
– etc/module.xml
– etc/frontend/events.xml
– Observer/Topmenu.php

First we will create registration file at app/code/Hiddentechies/NavLinks/registration.php file

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Hiddentechies_NavLinks',
    __DIR__
);

Now, create a composer.json file in app/code/Hiddentechies/NavLinks/ folder as per below.

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Hiddentechies_NavLinks',
    __DIR__
);

{
    "name": "hiddentechies/navlinks",
    "description": "N/A",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0"
    },
    "type": "magento2-module",
    "version": "1.0.2",
    "authors": [
        {
            "name": "Hiddentechies",
            "email": "[email protected]",
            "homepage": "https://www.Hiddentechies.com/",
            "role": "Developer"
        }
    ],
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Hiddentechies\\NavLinks\\": ""
        }
    }
}

now create module.xml file in app/code/Hiddentechies/NavLinks/etc

<?xml version="1.0"?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Hiddentechies_NavLinks" setup_version="1.0.0">
    </module>
</config>

now create events.xml file in app/code/Hiddentechies/NavLinks/etc/frontend

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="page_block_html_topmenu_gethtml_before">
        <observer name="hiddentechies_navlinks_observer" instance="Hiddentechies\NavLinks\Observer\Topmenu" />
    </event>
</config>

Now we will create Observer/Topmenu.php file.

<?php
namespace Hiddentechies\NavLinks\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Data\Tree\Node;
use Magento\Framework\Event\ObserverInterface;
class Topmenu implements ObserverInterface
{
    public function __construct(
        ...//add dependencies here if needed
    )
    {
    ...
    }
    /**
     * @param EventObserver $observer
     * @return $this
     */
    public function execute(EventObserver $observer)
    {
        /** @var \Magento\Framework\Data\Tree\Node $menu */
        $menu = $observer->getMenu();
        $tree = $menu->getTree();
        $data = [
            'name'      => __('Menu Lable'),
            'id'        => 'unique-id',
            'url'       => 'Menu URL',
            'is_active' => (expression to determine if menu item is selected or not)
        ];
        $node = new Node($data, 'id', $tree, $menu);
        $menu->addChild($node);
        return $this;
    }
}

Now run upgrade command php bin/magento setup:upgrade to install the module. Clear Magento 2 cache.

You have known all the steps to add new links to navigation menu of Magento 2. if you have any questions about this post, please ask them in comments.