Skip to content

Mukesh Chapagain Blog

  • PHP
    • PHP
    • Laravel
    • WordPress
    • Joomla
  • Magento
    • Magento 2
    • Magento Extension
  • Node.js
    • Node.js
    • Javascript
    • jQuery
  • Database
    • MySQL
    • MongoDB
  • Data Science
    • Machine Learning
    • Recommender System
    • Natural Language Processing (NLP)
    • Sentiment Analysis
    • Python
    • R
  • Categories
    • Blockchain
      • Hyperledger Composer
      • Hyperledger-Fabric
    • Other
      • Cryptography
      • Data Structures & Algorithms
      • Git
      • LaTeX
      • Linux
      • Ubuntu
      • Xubuntu
      • Google
      • Google AppScript
  • About
    • About
    • Contact
    • Privacy Policy

Home » Magento » Magento 2 » Magento 2: Add Custom Link/Tab & Page to Customer Account Sidebar

Magento 2: Add Custom Link/Tab & Page to Customer Account Sidebar

October 6, 2022February 11, 2019 by Mukesh Chapagain
Categories Magento, Magento 2 Tags account, customer, Magento, magento2, navigation, sidebar
FacebookTweetLinkedInPinPrintEmailShares

This article shows how you can add custom link or tab in the Customer account sidebar section.

I will also show how you add/show your custom page when you click on the newly added custom link in the customer account sidebar.

So, basically, we will be adding a custom link and linking it to a custom page. The custom page will also contain the customer account sidebar displayed.

Here’s how you do it:

Suppose, your module name is YourNamespace_YourModule.

Table of Contents

Toggle
  • 1) Create customer_account layout XML file
  • 2) Create your module’s routes.xml file
  • 3) Create your module’s layout XML file
  • 4) Create Controller class files
  • 5) Create Block class file
  • 6) Create Template files

1) Create customer_account layout XML file

Create the layout file at this location:

app/code/YourNamespace/YourModule/view/frontend/layout/customer_account.xml

Here, I have added two ways (one is commented out) to add the custom links in the customer account navigation sidebar.

– One will add the links at the bottom of the sidebar list
– The other has the sortOrder feature which can sort the custom links in any custom order

app/code/YourNamespace/YourModule/view/frontend/layout/customer_account.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_account_navigation">
            <!-- Add menu to the end of the sidebar -->
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-your-first-link">
                <arguments>
                    <argument name="path" xsi:type="string">yourmodule/yourfirstlink/index</argument>
                    <argument name="label" xsi:type="string">Your First Link</argument>
                </arguments>
            </block>
            <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-your-second-link">
                <arguments>
                    <argument name="path" xsi:type="string">yourmodule/yoursecondlink/index</argument>
                    <argument name="label" xsi:type="string">Your Second Link</argument>
                </arguments>
            </block>

            <!-- Add menu in the sidebar with sort order -->
            <!--
            <block class="Magento\Customer\Block\Account\SortLinkInterface" name="customer-account-navigation-your-first-link">
                <arguments>
                    <argument name="path" xsi:type="string">yourmodule/yourfirstlink/index</argument>
                    <argument name="label" xsi:type="string">Your First Link</argument>
                    <argument name="sortOrder" xsi:type="number">250</argument>
                </arguments>
            </block>
            <block class="Magento\Customer\Block\Account\SortLinkInterface" name="customer-account-navigation-your-second-link">
                <arguments>
                    <argument name="path" xsi:type="string">yourmodule/yoursecondlink/index</argument>
                    <argument name="label" xsi:type="string">Your Second Link</argument>
                    <argument name="sortOrder" xsi:type="number">260</argument>
                </arguments>
            </block>
            -->
        </referenceBlock>
    </body>
</page>

Showing Active Menu Link when clicked

There was one issue with showing the active menu link in the customer sidebar navigation.

My custom link was clicked and my custom page was displayed but the custom link was not highlighted. Highlighting the active menu link makes it easy to figure out on which page we are in.

To fix this issue, I had to remove the “action” path in the XML code.

In the above XML code, you can see that I have defined my custom menu path as:

<argument name="path" xsi:type="string">yourmodule/yourfirstlink/index</argument>

Here,

yourmodule = my module name
yourfirstlink = my module’s controller name
index = my controller’s action

I removed the ‘index’ text from the path, like this:

<argument name="path" xsi:type="string">yourmodule/yourfirstlink</argument>

Then, the active link issue was solved. Now, when I click on my custom menu link, it becomes highlighted.

TIP:

You can also remove customer sidebar menu items by writing the remove code in the customer_account.xml file you created inside your custom module.

app/code/YourNamespace/YourModule/view/frontend/layout/customer_account.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer-account-navigation-wish-list-link" remove="true"/>
    </body>
</page>

2) Create your module’s routes.xml file

The routes.xml file maps which module to use for a URL with a specific frontName.

For frontend URL mapping, we create routes file inside etc/frontend folder.
Similarly, for backend URL mapping, we create routes file inside etc/adminhtml folder.

app/code/YourNamespace/YourModule/etc/frontend/routes.xml
<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="productsinrange" frontName="productsinrange">
            <module name="YourNamespace_YourModule" />
        </route>
    </router>
</config>

3) Create your module’s layout XML file

We have defined two links. The paths of the links defined in the above XML code are:

– yourmodule/yourfirstlink/index
– yourmodule/yoursecondlink/index

These paths indicate the controller classpath of your module. These paths should also match the layout XML file name. Hence, we create two different XML files for each specified paths.

<update handle="customer_account"/>

Note:
This code is important in the below XML files. Without this code, the customer sidebar navigation menu will not appear on your custom pages.

We specify our custom Block class and link it to our firstlink phtml file.

app/code/YourNamespace/YourModule/view/frontend/layout/yourmodule_yourfirstlink_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <head>
        <title>
            Your First Link
        </title>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="YourNamespace\YourModule\Block\YourBlock" name="yourmodule.firstlink.index" template="YourNamespace_YourModule::yourfirstlink/index.phtml" cacheable="false" />
        </referenceContainer>
    </body>
</page>

We specify a general Template block class and link it to our second link phtml file.

app/code/YourNamespace/YourModule/view/frontend/layout/yourmodule_yoursecondlink_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <head>
        <title>
            Your Second Link
        </title>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="Magento\Framework\View\Element\Template" name="yourmodule.secondlink.index" template="YourNamespace_YourModule::yoursecondlink/index.phtml" cacheable="false" />
        </referenceContainer>
    </body>
</page>

4) Create Controller class files

We have specified two controller paths in the layout XML file. So, we create two controller classes.

app/code/YourNamespace/YourModule/Controller/YourFirstLink/Index.php
<?php
namespace YourNamespace\YourModule\Controller\YourFirstLink;
 
class Index extends \Magento\Framework\App\Action\Action
{
        /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;
 
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory resultPageFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory
        )
        {
            $this->resultPageFactory = $resultPageFactory;
            parent::__construct($context);
        }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        return $this->resultPageFactory->create();
    }
}
?>
app/code/YourNamespace/YourModule/Controller/YourSecondLink/Index.php
<?php
namespace YourNamespace\YourModule\Controller\YourSecondLink;
 
class Index extends \Magento\Framework\App\Action\Action
{
        /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;
 
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory resultPageFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory
        )
        {
            $this->resultPageFactory = $resultPageFactory;
            parent::__construct($context);
        }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        return $this->resultPageFactory->create();
    }
}
?>

5) Create Block class file

For our firstlink, we had defined our own custom Block class. So, we create the Block class now.

app/code/YourNamespace/YourModule/Block/YourBlock.php
<?php
namespace YourNamespace\YourModule\Block;
class YourBlock extends \Magento\Framework\View\Element\Template
{        
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,        
        array $data = []
    )
    {        
        parent::__construct($context, $data);
    }
    
    public function getHelloWorld()
    {
        return 'Hello World';
    }
    
}
?>

6) Create Template files

app/code/YourNamespace/YourModule/view/frontend/templates/firstlink/index.phtml
<h2>
    <?php echo $block->getHelloWorld(); ?>
</h2>

echo 'My First Link Page';
app/code/YourNamespace/YourModule/view/frontend/templates/secondlink/index.phtml
echo 'My Second Link Page';

Hope this helps. Thanks.

Related posts:

  1. Magento: Add new tab to Customer Account Section
  2. Magento 2: Customer Image/File Upload in Registration & Account Page
  3. Magento2: Programmatically Create Custom Layout XML
  4. Magento: Programmatically Remove Layout Block
Categories Magento, Magento 2 Tags account, customer, Magento, magento2, navigation, sidebar
Magento 2: Show Calendar/DatePicker & Date-Range Field in Custom Form
Magento 1 & 2: Join Collection to get Customer Fullname

About

Mukesh Chapagain Hi, I’m Mukesh Chapagain — a web developer, programmer, and tech enthusiast. Whether you're a beginner or an experienced developer, you’ll find tips, tutorials, and insights to help you navigate the ever-evolving world of technology. Happy coding! 🚀 about...

         

Subscribe via Email



Categories

Most Viewed

  • How to Calculate Inverter & Battery Backup Time? - 428,020 views
  • Very Simple Add, Edit, Delete, View (CRUD) in PHP & MySQL [Beginner Tutorial] - 415,646 views
  • LaTeX: Generate dummy text (lorem ipsum) in your document - 228,046 views
  • GPG: Remove keys from your public keyring? - 201,573 views
  • Magento: How to get attribute name and value? - 188,264 views

Recent Posts

  • Magento: The store that was requested wasn’t found. Verify the store and try again.
  • Magento2: Check Services version on Adobe Cloud Server
  • Magento 2 API: Add Products to Cart & Checkout Place Order
  • Magento 2 API: Create New Customer
  • Magento 2 API: Get Categories

Recent Posts

  • Magento: The store that was requested wasn’t found. Verify the store and try again.
  • Magento2: Check Services version on Adobe Cloud Server
  • Magento 2 API: Add Products to Cart & Checkout Place Order
  • Magento 2 API: Create New Customer
  • Magento 2 API: Get Categories

Most Viewed

  • How to Calculate Inverter & Battery Backup Time? - 428,020 views
  • Very Simple Add, Edit, Delete, View (CRUD) in PHP & MySQL [Beginner Tutorial] - 415,646 views
  • LaTeX: Generate dummy text (lorem ipsum) in your document - 228,046 views
  • GPG: Remove keys from your public keyring? - 201,573 views
  • Magento: How to get attribute name and value? - 188,264 views

Tag Cloud

admin Adobe Commerce api array attribute block category checkout CLI command line crud currency customer Database error extension git Google grid HTML image Javascript Joomla jQuery latex Linux login Magento magento2 magento 2 module MySQL natural language processing NLP nltk nodejs order PHP product python shopping cart template Ubuntu url Wordpress
© 2025 Mukesh Chapagain Blog
We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.OkPrivacy policy