There are Magento 2 bugs created concerning this issue:
https://github.com/magento/magento2/issues/4247
https://github.com/magento/magento2/issues/19196
I have only made a workaround by replacing admin URL with frontend store URL:
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
private $config;
/**
* Url constructor.
*
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
*/
public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $config)
{
$this->config = $config;
}
/**
* {@inheritdoc}
*/
public function getProductUrl(Product $product): string
{
$isSecure = $product->getStore()->isFrontUrlSecure();
$productUrl = $product->getUrlModel()->getUrl($product, ['_secure' => $isSecure]);
/**
* There is a Magento bug with getting product URL from adminhtml area:
* https://github.com/magento/magento2/issues/4247
* https://github.com/magento/magento2/issues/19196
*
* Making a workaround to return proper frontend product URL based on store
*/
if ($this->isAdminUrlUseCustom()) {
$productUrl = str_replace(
$this->getBaseUrl(0, $isSecure),
$this->getBaseUrl($product->getStoreId(), $isSecure),
$productUrl
);
}
return $productUrl;
}
/**
* Is admin URL use custom
*
* @return bool
*/
private function isAdminUrlUseCustom(): bool
{
return $this->config->isSetFlag('admin/url/use_custom');
}
/**
* Get base url for store
*
* @param int $storeId
* @param bool $isSecure
* @return string
*/
private function getBaseUrl(int $storeId, bool $isSecure): string
{
if ($isSecure || 0 === $storeId) {
return $this->config->getValue(
'web/secure/base_url',
\Magento\Store\Model\ScopeInterface::SCOPE_STORES,
$storeId
);
}
return $this->config->getValue(
'web/unsecure/base_url',
\Magento\Store\Model\ScopeInterface::SCOPE_STORES,
$storeId
);
}