Create dynamically link in customer account navigation in Magento 2

Create dynamically link in customer account navigation in Magento 2

We can create custom customer account link with reference block customer_account_navigation with a custom block class

1) Add block class in customer_account.xml

File: app/code/Vendor/Module/view/frontend/layout/customer_account.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_account_navigation">
            <block class="{vendor}\{Module}\Block\Customer\Link" name="customer-account-navigation-new-product-link" after="-">
                <arguments>
                    <argument name="label" xsi:type="string">Some link</argument>
                    <argument name="path" xsi:type="string">customer/somelink/index</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

2) Now create Link.php

namespace Vendor\Module\Block\Customer;

class Link extends \Magento\Framework\View\Element\Html\Link\Current
{
    protected $_customerSession;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Framework\App\DefaultPathInterface $defaultPath,
        \Magento\Customer\Model\Session $customerSession,
        array $data = []
     ) {
         $this->_customerSession = $customerSession;
         parent::__construct($context, $defaultPath, $data);
     }

    protected function _toHtml()
    {    
        $responseHtml = null; //  need to return at-least null
        if($this->_customerSession->isLoggedIn()) {
            $responseHtml = parent::_toHtml(); //Return link html
        }
        return $responseHtml;
    }
}

In the above code snippet, I added a custom link dynamically if the customer is loggedIn otherwise it returns null.

If you want only need to change url of navigation, Follow below step

1) Define helper class

File: app/code/Vendor/Module/view/frontend/layout/customer_account.xml

Define helper class {vendor}\{Module}\Helper\Data in the navigation link

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_account_navigation">
            <block class="Magento\Customer\Block\Account\SortLinkInterface" name="customer-account-navigation-new-product-link" after="-">
                <arguments>
                    <argument name="label" xsi:type="string">Some link</argument>
                    <argument name="path" xsi:type="helper" helper="{Vendor}\{Module}\Helper\Data::getLink"></argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

2) Add getLink() function in Data.php

File: app/code/{Vendor}/{Module}/Helper/Data.php

namespace Vendor\Module\Helper;

class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
    public function getLink()
    {
        //Do your logic and return link
        $link = "sales/order/mylink";

        return $link;
    }
}