Shopware 6 - Tips, tricks and how to's

Solved: Shopware 6 sitemap generates URLs with http instead of https

The problem: unexpected core behavior

Based on this Shopware 6 official forum post, asking about a possible problem with sitemaps being generated with http instead https, I have checked Shopware 6 stores under my jurisdiction and indeed found out, that the problem is there. So I immediately started debugging. My starting point was the command, that takes care of the sitemap generation:

It is located in vendor/shopware/core/Content/Sitemap/Commands/SitemapGenerateCommand.php. After some digging in the classes and methods, that this command calls, I have found the problem in vendor/shopware/core/Content/Sitemap/Service/SitemapExporter.php. To be more specific, the method getHost of this class goes through the domains, that were associated to a sales channel (plus language) and picks the URL of the first one, that it encounters. And that is exactly the problem here. If you have both http and https versions of the domain, then Shopware can select an unwanted version as a base for your URLs.

Is this a bug? Maybe, maybe not.. But it could have certainly been handled better. The best option would be, if there was a setting in Administration, that would allow you to designate, which domain should be preffered in case there is more of them for a combination of sales channel and language. Alas, there is no such setting yet or I have not found it. To be honest, I think, that in most cases, people would prefer to use https over http. So the programmatic solution, that I will present here will be counting on that.

If some of the core functionality is not good enough or does not work, as we would like it to work, we have an option to override it from our custom plugin. And that is exactly what we are going to do. I will just assume, that we already have a plugin and describe just the parts, that are necessary for this solution.

The solution: class override

Step one – create an overiding class

First, we need to override the Shopware class, that contains the inconvenient code. So we will create a file, that will be named precisely the same, as the original and put it into a similar directory structure. In case of core class vendor/shopware/core/Content/Sitemap/Service/SitemapExporter.php the path to our override class within our plugin would be src/Core/Content/Sitemap/Service/SitemapExporter.php. My plugin is named ShopwareFixes (yes, I have already overridden some other stuff from the core 😀 ), so the result will look something like this:

I consider retaining the path a good practice for a better orientation in the code, but it probably is not a requirement. Now we copy the contents of the original file to the new one and do the necessary edits:

  • change the namespace to reflect the location of the override
  • add ‘use’ for the classes, that were omitted in the original class, because they were in the same namespace
  • change the logic of the getHost method

This is how the override looks like after the edits:

Step 2 – tell Shopware to use the override

Now we have to tell Shopware 6, that we want it to use our class instead of the original from the core. This is done in the services.xml file, located in the src/Resource/config. We need to add a new entry for our class (=service), where we specify, which class it overrides (=decorates in Symfony terminology). And as with any other services in Shopware 6, this one has to have its dependency injections specified as arguments.

Because the original class has quite a lot of dependencies, it is best to find the services.xml file, that contains the original class and copy them to our file.

The resulting file services.xml for our override looks like this:

The last argument contains the injection of the original class, but in this case we do not need it.

And that is it, problem solved. If you now run the sitemap generation command again and you have a https domain in your sales channel, it will be used for URL generation for your sitemaps.