Magento – Magento 2 get frontend store url for a path in admin

magento-2.1magento2

In admin code, i would like to get the frontend store url for a path. But, always getting admin url for the path.

$storeId = $this->_storeManager->getDefaultStoreView()->getStoreId();
$url = $this->_storeManager->getStore($storeId)->getUrl("sample/index/test");

Expected result in http://{magento-url}/sample/index/test/, but always getting http://{magento-url}/{admin-path}/sample/index/test/

Checked the store model, the getUrl function uses Magento\Backend\Model\Url to get the store url.

Can anybody please, let me know the correct way to get the store url from admin page.

namespace VendorName\ModuleName\Model;

use VendorName\ModuleName\Helper\Data as ModuleHelper;
use Magento\Store\Model\StoreManagerInterface;

class Api {

    protected $_helper;

    public function __construct(ModuleHelper $helper, StoreManagerInterface $storeManager) {
        $this->_helper = $helper;
        $this->_storeManager = $storeManager;
    }

    public function doSomeAction() {
        //$customUrl = $this->_storeManager->getStore()->getBaseUrl() . "/sample/index/test";
        $customUrl = $this->_helper->getCustomUrl();
        echo $customUrl;
    }

}


namespace VendorName\ModuleName\Helper;

use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\StoreManagerInterface;

class Data extends \Magento\Framework\App\Helper\AbstractHelper {

    protected $_storeManager;

    public function __construct(Context $context, StoreManagerInterface $storeManager) {
        parent::__construct($context);
        $this->_storeManager = $storeManager;
    }

    public function getCustomUrl() {
        $storeId = $this->_storeManager->getDefaultStoreView()->getStoreId();
        return $this->_storeManager->getStore($storeId)->getUrl("sample/index/test");
    }

}

Best Answer

Might be too late for OP, but hopefully this helps anyone else that lands on this page with the same issue.

The reason you are not getting the frontend URL is due to a preference defined in the core code, specifically:

magento/module-backend/etc/adminhtml/di.xml (line 12 in CEv2.1)

<preference for="Magento\Framework\UrlInterface" type="Magento\Backend\Model\UrlInterface" />

In order to solve it you have two options

1) Create your own preference for UrlInterface (in your own module), and determine in your code when the backend/frontend URL should be returned. (strictly speaking, this would be most in-line with Magento code guidelines, but IMO is overkill if you only need it a few times)

2) Call the frontend Url.php (which implements UrlInterface) in the constructor of the file you need to get the URL in. This will bypass the preference and give you a frontend URL. Partial code example shown below

/** @var \Magento\Framework\Url */
protected $urlHelper;

public function __construct(
    <<insert your other required files here>>
    \Magento\Framework\Url $urlHelper,
) {
    <<insert parent/other required objects here>>
    $this->urlHelper = $urlHelper;
}

public function getFrontendUrl($routePath, $routeParams)
{
    return $this->urlHelper->getUrl($routePath, $routeParams)
}

public function yourFunction()
{
    $url = $this->getFrontendUrl(
        'quotes/history/view',
        array(  //any parameters should be passed in array format
            'id' => $mageQuote->getId(), 
            '_nosid' => true  //prevents sessionId from getting added
        )
    );
    // $url = 'https://www.domainname.com/quotes/history/view/id/###/'
}