Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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.

...

Code Block
composer require "creativestyle/magesuite-seo-hreflang" ^1.0.0

Admin settings

Admin setting 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 

  • Store Group 

Global - hreflang links will be displayed for all store views from all websites.
Store Group - hreflang links will be displayed only for store views from current store group.

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.

Note

TODO - BE documentation and review of documentation is needed

vendor/creativestyle/magesuite-seo-hreflang/view/frontend/templates/hreflang.phtml
Code Block
$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
Code Block
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
Code Block
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);
    }
}

If there is no $urlRewrite, we go into $store->getCurrentUrl(false) and also into below plugin

vendor/creativestyle/magesuite-seo-hreflang/Plugin/Model/Store.php:61
Code Block
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.