2

For SEO reasons we would like to switch stores directly without the default store switchers redirect chain.

The normal Magento store switcher creates a redirect chain when switching store. For example switching from example.de/baelle to example.com/balls does the following:

  • example.de/baelle
  • 302 -> example.de/stores/store/redirect
  • 302 -> example.com/stores/store/switch?___from_store=de&___store=en&data=hash&signature=hash
  • 302 -> example.com/balls

This is bad for SEO and leads to tons of unnecessary urls showing up in search engine crawls.

Our first idea was replacing the store switcher template and using \Magento\Store\Model\StoreSwitcherInterface::switch in order to create the target url.
Something like this:

<?php foreach ($website->getStoreCollection() as $_store): ?>
    <?php if (
        $_store->getId() != $block->getCurrentStoreId()
        && $_store->isActive()
    ): ?>
        <li class="view-<?= $block->escapeHtml($_store->getCode()); ?> switcher-option">
            <a href="<?= $block->escapeHtml(
                $viewModel->getDirectLink(
                    $_store,
                    $block->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true])
                )
            ) ?>" class="text-white">
                <?= $block->escapeHtml($viewModel->getStoreSwitchLabel($_store)) ?>
            </a>
        </li>
    <?php endif; ?>
<?php endforeach; ?>

And in the view model:

public function getDirectLink(Store $_store, string $currentUrl): string
{
    $currentStore = $this->storeManager->getStore();
    $redirectUrl = "{$currentUrl}?___from_store={$currentStore->getCode()}";

    /** \Magento\Store\Model\StoreSwitcherInterface $this->storeSwitcher */
    return $this->storeSwitcher->switch($currentStore, $_store, $redirectUrl);
}

But this messes with the cookies and does not seem to work properly. In \Magento\Store\Model\StoreSwitcher\ManageStoreCookie::switch Magento then deletes the store cookie and sets it based on the passed store. So if I am in de I will get the en cookie and the en based content.

My question is if there are already extensions that replace the default store switcher and do a simple link to the according url of the store the user would like to switch to. Or if not is there a better way to generate the url?

3
  • 1
    What do you mean with "messes with the cookies" ?
    – Alex
    May 22 at 10:37
  • Also I would like to add a 3rd aspect to the original question: Why is Magento using so many redirects by default ?
    – Alex
    May 22 at 10:38
  • I added an explanation about the cookies. Regarding the many redirects my presumption is that magento is able to run all stores/websites on the same url and handles which store is active via cookie. So in order to set the correct cookies and urls at least one redirect is necessary.
    – Daniel
    May 22 at 12:10

2 Answers 2

2

I'm not aware of any specific extensions that replace the default store switcher in Magento and provide a direct link to the target store URL without the redirect chain. However, you can achieve this functionality by implementing a custom solution. Here's a suggested approach:

Create a custom module: Create a new custom module or use an existing one in your Magento 2 installation.

Override the store switcher template: In your module, override the store switcher template file (vendor/magento/module-directory/view/frontend/templates/currency.phtml for currency switcher or vendor/magento/module-directory/view/frontend/templates/store_switcher.phtml for store switcher). Copy the file to your custom module's directory structure, preserving the same file path.

Modify the template: In your overridden template file, modify the code as per your requirement. Instead of using the default store switcher behavior that generates the redirect chain, you can directly link to the target store URL. Here's an example of how you can structure the code:

getStoreCollection() as $_store): ?>
<?php if (
    $_store->getId() != $block->getCurrentStoreId()
    && $_store->isActive()
): ?>
    <li class="view-<?= $block->escapeHtml($_store->getCode()); ?> switcher-option">
        <a href="<?= $block->escapeUrl($_store->getBaseUrl()) ?>" class="text-white">
            <?= $block->escapeHtml($viewModel->getStoreSwitchLabel($_store)) ?>
        </a>
    </li>
<?php endif; ?>

In this example, instead of generating a URL with the redirect chain, we directly use $block->escapeUrl($_store->getBaseUrl()) to get the target store's base URL. Adjust the code according to your specific requirements and whether you're modifying the currency switcher or store switcher template.

Clear the cache and test: Save the modified file, clear the Magento cache, and test the store switcher functionality on your website. Ensure that the links direct users to the target store URL without the redirect chain. Remember to follow proper Magento 2 module development practices and adjust the code as per your specific requirements and file paths in your custom module.

Implementing this custom solution allows you to generate direct links to the target store URLs without the redirect chain, potentially improving SEO and avoiding unnecessary URLs.

1
  • 1
    The problem here is that only the base url is used and the customer would always change to the homepage. Our requirement is that the customer stays on the same page.
    – Daniel
    May 22 at 13:56
1

The \Magento\Store\Model\StoreSwitcherInterface::switch calls multiple defined switchers. Those are defined in Magento/Store/etc /di.xml and Magento/UrlRewrite/etc /di.xml as of Magento 2.4.6. One of them is \Magento\UrlRewrite\Model\StoreSwitcher\RewriteUrl this will look for the current rewrite and get the counterpart for the passed store. See \Magento\UrlRewrite\Model\StoreSwitcher\RewriteUrl::switch for detailed information.

So by providing the current url and the desired store it is possible to get a direct url for the target store.

To implement this the original template must be overwritten and a view model can be used to get the direct link. The template stays the same as in the question but the view model changes to:

public function getDirectLink(Store $_store, string $currentUrl): string
{
    /** \Magento\UrlRewrite\Model\StoreSwitcher\RewriteUrl $this->storeSwitcher */
    $newUrl = $this->storeSwitcher->switch($this->storeManager->getStore(), $_store, $currentUrl);

    if ($newUrl === $currentUrl) {
        return $_store->getBaseUrl();
    }

    return $newUrl;
}

It is important to check if the current url matches the new url because the homepage or cms pages that are the same page with different identifiers (url keys) will not have a matching rewrite. In such a case the base url of the target store will be returned.

A working example can be seen in our magento2-store-switch-all-store-views extension. I have implemented this approach in the module.

Please be aware that this will not work with stores/websites that share the complete urls because then the store will be managed via cookies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.