Add Custom Sitemap Entries
Overview
Of course Shopware comes with a sitemap generation feature, including products and categories, as well as some more URLs. This guide however will cover how you can add your own custom URLs to the sitemap.
By using the configuration
To add a custom URL to the sitemap, use the configuration setting shopware.sitemap.custom_urls
shopware:
sitemap:
custom_urls:
- url: 'custom-url'
salesChannelId: '98432def39fc4624b33213a56b8c944d'
changeFreq: 'weekly'
priority: 0.5
lastMod: '2024-09-19 12:19:00'
- url: 'custom-url-2'
salesChannelId: '98432def39fc4624b33213a56b8c944d'
changeFreq: 'weekly'
priority: 0.5
lastMod: '2024-09-18 12:18:00'
The salesChannelId
is the ID of the sales channel you want to add the URL to.
By adding a URL provider
This part of the guide is mainly built upon the guide about [Adding a custom SEO URL](../seo/add-custom-seo-url#Dynamic SEO URLs for entities), so you might want to have a look at that. The said guide comes with a custom entity, a controller with a technical route to display each entity, and a custom SEO URL. All of this will be needed for this guide, as we're going to add the custom entity SEO URLs to the sitemap here.
So let's get started. Adding custom URLs to the sitemap is done by adding a so-called "URL provider" to the system.
This is done by adding a new class, which is extending from Shopware\Core\Content\Sitemap\Provider\AbstractUrlProvider
. It then has to be registered to the service container using the tag shopware.sitemap_url_provider
.
It has to provide three methods:
getDecorated
: Just throw an exception of typeDecorationPatternException
here. This is done for the sake of extending a class via decoration. Learn more about this here.getName
: A technical name for your custom URLsgetUrls
: The main method to take care of. It has to return an instance ofShopware\Core\Content\Sitemap\Struct\UrlResult
, containing an array of all URLs to be added.
Let's have a look at the example class:
Let's go through this step by step. First of all we created a new class CustomUrlProvider
, which is extending from the AbstractUrlProvider
. Following are the constants CHANGE_FREQ
and priority
- you don't have to add those values as constants of course. They're going to be used later in the generation of the sitemap URLs.
Passed into the constructor are the repository for our custom entity, the DBAL connection used for actually fetching SEO URLs from the database, and the Symfony router in order to generate SEO URLs that have not yet been written to the database.
Now let's get to the main method getUrls
. Here we start of with fetching all custom entities, using the provided $limit
and $offset
values. Make sure to always use those values, as the sitemap support "paging" and therefore you do not want to simply fetch all of your entities. If there aren't any entities to be fetched, there is nothing more to be done here.
Afterwards we fetch all already existing SEO URLs for our custom entities. Once again, have a look at our guide about [adding a custom SEO URL](../seo/add-custom-seo-url#Dynamic SEO URLs for entities) if you don't know how to add custom SEO URLs in the first place.
We're then iterating over all of our fetched entities and we create an instance of Shopware\Core\Content\Sitemap\Struct\Url
for each iteration. This struct requests each of the typical sitemap information:
lastMod
: The last time this entry was modified. Just use theupdatedAt
value here, if availablechangeFreq
: How often will the entry most likely change? Possible values arealways
,hourly
,daily
,weekly
,monthly
,yearly
andnever
priority
: Has to have a value between 0 and 1. URLs with higher priority are considered to be "more important" by common search engines.resource
: Just a name for your entry, in this example we're just using the entity class nameidentifier
: The ID of the entry, if available
The most important entry is set afterwards, which is the location
: The actual SEO URL to be indexed. We're setting this value by checking if the SEO URL for the given entity was already generated, and if not, we're generating it on the fly.
All of those instances are then stored in array, which in return is passed to the UrlResult
. And that's it already!