Worth knowing about Shopware's SEO URL system

How SEO URLs work in Shopware, and how to customize them.

345 views
d

By. Jacob

Edited: 2023-03-03 09:50

Shopware uses Slugify to generate URLs for categories and products. The URLs are auto-generated on-the-fly or when running dal:refresh:index from a console.

Note. You may want to consider running this with the --use-queue option, as doing so will send the URL generation tasks to the queue system instead of running everything at once.

You may want to add a dal:refresh:index --use-queue to be executed at night time by cron, but I am not yet sure this is necessary.

The --use-queue can be useful on test servers that may not have as many resources as your live environment. The URL generation will then be handled by your messenger:consume workers over a period of time. You can install frosh tools to monitor the progress in the administration backend, and specifically it's the indexing messages that are created by dal:refresh:index you want to monitor.

If you only want to re-generate URLs for the products, you can use the --only option. E.g:

sudo -u www-data bin/console dal:refresh:index --use-queue --only=product.indexer

URLs are stored in the seo_url table in the database. If you have not manually changed URLs on products and categories, you will typically be able to truncate this table without having to worry about broken URLs and adding 301 redirects; this will allow the system to re-generate everything in the seo_url table. It is not usually recommended to truncate the table unless you are having problems or you are testing custom code.

Keep in mind, a unique URL can exist for each translation, so this is a fairly complex system, and truncating the table on a live webshop is probably going to result in a lot of 404 errors. The table also contains redirects from old URLs, and you will also lose those if you truncate the table.

Defining a URL pattern

The URLs generated by Shopware will be created according to a template that can be defined in the administration. E.g. In the settings -> SEO area.

A good template for products can look like this:

p/{{ product.translated.name|lower }}

But, this may create occasional conflicts with duplicated product titles, which may then result in URLs not being generated for the affected products. E.g:

/detail/[product-id]

It is possible to solve this problem, but ideally Shopware ought to just add something to the end of the URL. E.g. "-1" or even just "-[product-number] in those cases. It doesn’t currently do that, so instead you get bugged URLs.

Unfortunately, we can not simply correct the URLs manually, because Shopware will not allow that. The SEO URL section is deactivated / grayed out, showing the message:

There are no SEO URLs yet.
Main category

I am not even sure what the "Main category" piece of text is supposed to mean in this context.

What can be done to solve this problem?

Since Shopware uses Slugify to generate the URLs, we can just create a decorator for Slugify, and add a custom rule for how to handle these specific situations. E.g. "+" in the title of products.

Note. I will show how to make your own decorator-plugin that deals with this specific situation in a later post.

URLs should be lowercase

Because a specific URL in lowercase is not the same when written in uppercase, ideally caps should be banned in URLs. In other words, uppercase URLs could refer to entirely different resources than their lowercase counterparts.

Unfortunately you can not simply setup a redirect from uppercase to lowercase, because that will also affect Shopware's API endpoints, so you will have to make the redirect only apply to categories and products somehow.

In the SEO URL templates section, you can use the "lower" filter to convert your URLs to lowercase automatically. E.g:

For products:

p/{{ product.translated.name|lower }}

This is an ideal format for products. Do not include the category in the URL, because it is redundant, and it does not add SEO value.

For categories:

c/{% for part in category.seoBreadcrumb %}{{ part|lower }}/{% endfor %}

For blog posts:

blog/{{ blogpost.translated.slug|lower }}

Remember to setup a 301 redirect from the uppercase version to the lowercase version. In PHP, from a plugin, this can be done with a simple preg_match.

SEO URLs is a misnomer

The fact that URLs are named "SEO URLs" is also a misnomer; URLs has very little to do with SEO; they are first and foremost a way to identify a resource. Calling them "SEO URLs" may also have the unfortunate side-effect that people might erroneously think of their URLs as a matter of SEO, when we should think more in terms of usability.

Note. I am not saying you shouldn’t care at all, because then you might as well use the default database IDs. NO! Do it properly, do it once, and stop obsessing over URLs effect on SEO.

Product numbers in URLs

By default it seems Shopware is including the product number in the URL, which just looks horrendous, and seems to be a lazy solution to a problem with duplicated product titles.

In addition to this, it also seems like Shopware is ignoring characters that are valid in the path part, that is, they are simply removed rather than substituted. E.g. "+" is removed, and a "plus" version of a product erroneously result in a duplicated URL, and the URL for one of the products will not be generated.

Of course, there are very little, if any, SEO impact from having the product number in the URL – not having it just looks more polished.

The /p/ part is also bad, because it is basically redundant. However, it makes sense because we have other pages on the domain which are not "products". The "p" obviously stand for "product", and does not necessarily need translation.

Remember, each URL can be different depending on the translation and the sales channel.

URLs on company pages

Another annoying thing with Shopware is that you have to create a category if you want to create a basic "page", and those URLs might end up looking like this:

/c/about-us
/c/contact
/c/privacy

You have to manually change them after creating the pages, because Shopware will think that they are categories. Technically speaking, they are, but their actual function is different from a category.

Forward slashes

Forward slashes is another issue that many content managemen systems get wrong, including Shopware.

The bad thing about carelessly using forward slashes is that they are also used to indicate a category or directory on the web server.

Of course most users don't care about URL design, but that does not mean we should ignore it, as developers. So called trailing slashes should be banned for this reason – you are on a product page, not a directory page. Having a trailing slash is also redundant, and it adds ambiguity as to what is meant. Please think about your URL design!

If you do use trailing slash, it does have one benefit however – that is, if your URL ends with a dot .. E.g. /p/some-product-name.; If someone shares this URL by e-mail or in a messenger client, the client can not tell the difference between a dot in a sentence and a dot in a URL that someone copy paste into a message, and typically they will just strip away the dot, which then causes the URL to "break", and when a user clicks it, they will get a 404 – a slash at the end will fix that problem.

Read: Using Dots in URLs

Tell us what you think:

  1. Sometimes we may to manually clear cached Shopware files to fix namespace issues.
  2. How to obtain the currently selected API language from Shopware vue components.
  3. How to access file system paths from storefront twig files in Shopware.
  4. How to get or change the currently selected sales channel in an Shopware sw-sales-channel-switch component.
  5. In this tutorial you will learn how to work with Shopware entities in a generic way from PHP, without having to specifically inject the repository in your services.xml file.

More in: Shopware