https://github.com/magesuite/seo-hreflang/blob/1.x/etc/adminhtml/system.xml
This module adds hreflang tags for language and regional URLs used by search engines.
see https://support.google.com/webmasters/answer/189077
Installation
This module is a part of MageSuite metapackage
Installation if metapackage is not used:
composer require "creativestyle/magesuite-seo-hreflang" ^1.0.0
Admin settings
To define hreflang per Store View visit:
Stores -> All Stores -> [Store view] -> Store View Information
General admin settings for the module can be found in MageSuite section:
Store -> Configuration -> MageSuite -> SEO -> Configuration
Default scope settings:
Name | Options | Note |
---|---|---|
Hreflang Tags | Yes/No | Hreflang tags help the search engines to select best language version of the shop for incoming users. |
Hreflang Scope |
| Global - hreflang links will be displayed for all store views from all websites. |
X-Default | None / Specific website | Tells which storeview should be recommended for international audience. Read more. |
Website/Store scope settings:
Name | Options | Note |
---|---|---|
Exclude store | Yes/No | Exclude the store from the canonical URL list. |
Backend
It is required that language and region codes are separated by dash "-" instead of underscore "_" which Magento returns.
TODO - BE documentation and review of documentation is needed
vendor/creativestyle/magesuite-seo-hreflang/view/frontend/templates/hreflang.phtml
$viewModel = $block->getViewModel(); ?> <?php foreach ($viewModel->getAlternateLinks() as $alternateLink) : ?> <link rel="alternate" href="<?= $escaper->escapeHtml($alternateLink->getUrl()); ?>" hreflang="<?= $escaper->escapeHtml($alternateLink->getCode()); ?>"> <?php endforeach;?>
vendor/creativestyle/magesuite-seo-hreflang/ViewModel/Hreflang.php:50
class Hreflang implements \Magento\Framework\View\Element\Block\ArgumentInterface { public function getAlternateLinks(): array { $entity = $this->entityPool->getEntity(); ..... $stores = $this->getStores(); $alternateLinks = []; foreach ($stores as $store) { ..... $alternateLink = $this->getAlternateLink($entity, $store); ..... $alternateLinks[$store->getId()] = $alternateLink; } $this->addXDefaultUrl($alternateLinks); return $alternateLinks; } protected function getAlternateLink( \MageSuite\SeoHreflang\Model\Entity\EntityInterface $entity, \Magento\Store\Model\Store $store ): ?\Magento\Framework\DataObject { $url = $entity->getUrl($store); ..... $url = $this->addQueryToUrl($url); $alternateLink = [ 'url' => $url, 'code' => $this->getHreflangCode($store) ]; return new \Magento\Framework\DataObject($alternateLink); } /** * It is required that language and region codes are separated by dash "-" * instead of underscore "_" which Magento returns. */ protected function getHreflangCode(\Magento\Store\Model\Store $store): string { return $store->getHreflangCode() ?? str_replace('_', '-', $store->getCode()); } }
There can be different entities: Brand, Category, CmsPage, Product
for example:
vendor/creativestyle/magesuite-seo-hreflang/Model/Entity/Category.php:52
class Category implements EntityInterface { public function getUrl(\Magento\Store\Api\Data\StoreInterface $store): string { $urlRewrite = $this->urlFinder->findOneByData([ 'target_path' => trim($this->request->getPathInfo(), '/'), 'store_id' => $store->getId() ]); if ($urlRewrite) { return $store->getBaseUrl() . $urlRewrite->getRequestPath(); } return $store->getCurrentUrl(false); } }
vendor/creativestyle/magesuite-seo-hreflang/Plugin/Model/Store.php:61
class Store { public function aroundGetCurrentUrl( \Magento\Store\Model\Store $subject, callable $proceed, $fromStore = true ): string { if (version_compare($this->productMetadata->getVersion(), '2.3.5', '<')) { $sidQueryParam = $this->sidResolver->getSessionIdQueryParam($this->_getSession($subject->getCode())); } ..... $currentUrl = $storeParsedUrl->getScheme() . '://' . $storeParsedUrl->getHost() . (!$isDefaultPort ? ':' . $storeParsedUrl->getPort() : '') . $storeParsedUrl->getPath() . $requestString . ($storeParsedQuery ? '?' . http_build_query($storeParsedQuery) : ''); return $currentUrl; } }
Frontend
There is no frontend functionality in this module.