Magento2 | PWA | GraphQL

How to add Custom link in top navigation menu Magento2


There are several ways to add custom link in top navigation or topmenu in Magento 2.

If you are adding in your theme create default.xml in following path.

Layout Method

app/design/frontend/custom/theme/Magento_Theme/layout/default.xml

Or you want it to add from module layout then create default.xml in following path.

app/code/Magelearn/Topmenulink/view/frontend/layout/default.xml

Now add the following code, you can label and url ask you required.
<referenceBlock name="catalog.topnav">        
    <block class="Magento\Framework\View\Element\Html\Link\Current" name="cart" before="account">
               <arguments>
                       <argument name="label" xsi:type="string">Cart</argument>
                      <argument name="path" xsi:type="string">checkout/cart</argument>          
               </arguments>            
    </block>
</referenceBlock>

With Custom Extension

First we will create basic module structure and necessary files. After we will check different methods to do this task.

Create module.xml file at app/code/Magelearn/Topmenulink/etc/module.xml
<?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="Magelearn_Topmenulink" setup_version="1.0.0">
	</module>
</config>
Create registration.php file at app/code/Magelearn/Topmenulink/registration.php
<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
	ComponentRegistrar::MODULE,
	'Magelearn_Topmenulink',
	__DIR__
);
Create composer.json file at app/code/Magelearn/Topmenulink/composer.json
{
	"name": "magelearn/module-topmenulink",
	"description": "A module that adds cutom link at top navigation menu",
	"type": "magento2-module",
	"version": "1.0.0",
	"license": ["OSL-3.0", "AFL-3.0"],
	"require": {
		"php": "~7.1.3||~7.2.0||~7.3.0"
	},
	"autoload": {
		"files": ["registration.php"],
		"psr-4": {
			"Magelearn\\Topmenulink\\": ""
		}
	}
}
Now we have done with basic module structure. Let's first start with 

Event/Observer

Create file events.xml at app/code/Magelearn/Topmenulink/etc/frontend/events.xml
<?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="Magelearn_Topmenulink_Topmenu" instance="Magelearn\Topmenulink\Observer\Topmenu" />
    </event>
</config>
and create observer file Topmenu.php at app/code/Magelearn/Topmenulink/Observer/Topmenu.php
<?php
namespace Magelearn\Topmenulink\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 item label here'),
            'id'        => 'some-unique-id-here',
            'url'       => 'url goes here',
            'has_active' => false,
            'is_active' => (expression to determine if menu item is selected or not)
        ];
        $node = new Node($data, 'id', $tree, $menu);
        $menu->addChild($node);
        return $this;
    }
}

Plugin Method

for plugin Create di.xml file at app/code/Magelearn/Topmenulink/etc/frontend/di.xml
<?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="magelearn-topmenulink-topmenu" type="Magelearn\Topmenulink\Plugin\Block\Topmenu" />
	</type>
</config>
and create the plugin class file app/code/Magelearn/Topmenulink/Plugin/Block/Topmenu.php
<?php 

namespace Magelearn\Topmenulink\Plugin\Block;

use Magento\Framework\Data\Tree\NodeFactory;

class Topmenu
{
    /**
     * @var NodeFactory
     */
    protected $nodeFactory;

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

    public function beforeGetHtml(
        \Magento\Theme\Block\Html\Topmenu $topmenu,
        $outermostClass = '',
        $childrenWrapClass = '',
        $limit = 0
    ) {
        $node = $this->nodeFactory->create(
            [
                'data' => $this->getNodeAsArray(),
                'idField' => 'id',
                'tree' => $topmenu->getMenu()->getTree()
] ); $topmenu->getMenu()->addChild($node); } protected function getNodeAsArray() { return [ '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) ]; } }
The same functionality can also be achieved with afterGetHtml
<?php 

namespace Magelearn\Topmenulink\Plugin\Block;
use Magento\Framework\Data\Tree\Node;

class Topmenu implements ObserverInterface
{
    public function afterGetHtml(
    	\Magento\Theme\Block\Html\Topmenu $topmenu,
    	$html
    )
    {
        $itemUrl = $topmenu->getUrl('helloworld');//add link here
        $currentUrl = $topmenu->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true]);
        if (strpos($currentUrl,'helloworld') !== false) {
            $html .= "<li class="level0 nav-5 active level-top parent ui-menu-item">";
        } else {
            $html .= "<li class="level0 nav-4 level-top parent ui-menu-item">";
        }
        $html .= "<a href="" . $itemUrl . "" class="level-top ui-corner-all"><span class="ui-menu-icon ui-icon ui-icon-carat-1-e"></span><span>" . __("Hello World") . "</span></a>";
        $html .= "</li>";
        return $html;
    }
}
Tag : Magento2
0 Comments On "How to add Custom link in top navigation menu Magento2 "

Back To Top