Hi, ich bearbeite bei uns gerade ein ähnliches Problem, bzw. eigentlich genau das gleiche Problem, denn unsere Varianten-Artikel erhalten keine schönen, sprechenden URLs, sondern nur sowas wie „/detail/0902ed46b9044065a055b8a56ec75611“.
Im Issue Tracker wurde das Problem so beantwortet:
This does not work because the following associations are not loaded in \Shopware\Storefront\Framework\Seo\SeoUrlRoute\ProductPageSeoUrlRoute::prepareCriteria
options
options.group
Loading these would reduce the performance for product writes.
Ich frage mich gerade nur konkret, ob das Einbeziehen der fehlenden Assoziation wirklich so ein krasses Performance-Problem ist, wenn es in den URL-Templates aber einen großen Mehrwert bietet. Für mich erscheint die Verwendung von {{ product.variation }} tatsächlich auch am logischsten.
Wenn es aber einen anderen best practice gibt, wie sieht dieser dann aus? Im Hintergrund steht, dass wir eine alte URL-Struktur von Shopware 5 übernehmen, die durch die URL-Templates aber größtenteils mit den URLs aus dem neuen Shopware 6 System übereinstimmt, wodurch wir nur wenige 301 Weiterleitungen eintragen müssen. Das wäre auch für viele Kunden denke ich ein wichtiger Punkt.
Außerdem habe ich bei den Kategorie-URLs aktuell auch das Problem, dass mein URL-Template dort nicht angenommen wird, im Frontend erscheinen URLs wie: „/navigation/3f06f31237da4984b0b330641e03a03f“. Im URL-Template überspringe ich nur das erste Child der For-Schleife: {% for part in category.seoBreadcrumb %}{% if loop.index > 1 %}{{ part|lower }}/{% endif %}{% endfor %}
Die Vorschau unter dem Eingabefeld zeigt auch das richtige Ergebnis.
leider bin ich in diesem Punkt sehr enttäuscht von Shopware 6. Evtl. ist dir auch schon aufgefallen, dass dies ein massives Problem für die Shop SEO eines jeden Shopbetreibers ist und Shopware selbst schiebt das Problem laut Issuetracker immer wieder auf Backlog, sprich zeitlich weiter hinaus. Sie nehmen das Problem also nicht so ernst wie es tatsächlich ist.
Zwei Lösungsansätze gibt es:
Entweder du löst das Problem selbst indem Du eine Extension schreibst und die Variation durch ein Criteria Objekt selbst holst oder…
Ich habe mich an letzteres gewendet, da es schnell gehen musste, und wir uns nicht leisten konnten das Ranking des Kunden zu verhauen. Ein Plugin zu kaufen um eine Basic SEO Funktion zu bekommen, die der Shopware Core an sich so nicht unterstützt, finde ich schon sehr schwach. Man braucht nämlich keinen Shop auf Shopware 6 umziehen, wenn diese Funktion nicht gegeben ist. Sonst verliert man einen Großteil seiner Rankings und hat hässliche URLs noch dazu.
Eine weitere mögliche Lösung wäre:
Alle Varianten URLs hässlich zu lassen aber per Canonical auf den Parent zu zeigen. So sollte es eigentlich auch sein, sonst bekommst Du Duplicate Content, da jede Variante als eigenes Produkt indexiert wird. Das geht auch relativ schnell selbst in der meta.html.twig anzupassen:
oder Du benutzt folgendes Community Plugin, welches genau dasselbe macht:
Shopware lässt es ja nur zu auf eine Variante als Canonical für alle anderen Varianten zu nehmen, was aus SEO Sicht auch wieder absoluter Schwachsinn ist. Man will immer auf den Parent linken und nicht auf irgendeine Variante…
Hallo Luca, vielen Dank, eine bessere Antwort hätte ich mir nicht wünschen können! Großes Lob, sehr ausführlich und genau die Punkte angesprochen, die mich auch beschäftigen. Wir werden das intern einmal durchkauen. Das Plugin ist vermutlich für die meisten Kunden sehr hilfreich, für unsere Varianten könnte allerdings auch die Canonical Lösung schon ausreichen.
Ich habe mir nochmal dein Kategorie URL Problem durchgelesen. Auch wenn der twig Syntax korrekt ist, kannst du folgendes noch probieren:
{% for part in category.seoBreadcrumb %}{% if not loop.first %}{{ part|lower }}/{% endif %}{% endfor %}
Ist zwar genau dasselbe, aber mir ist bei der ganzen SEO URL Generierungsthematik aufgefallen, dass das Ergebnis der tatsächlich generierten URLs nicht immer ganz zum Twig Syntax passt. Probieren kannst du es ja mal.
Nicht vergessen die Indizes zu refreshen und cache zu leeren.
nochmal vielen Dank für Deine Hilfe! not loop.first ist an sich definitiv besser als if loop.index > 1. Ich habe in dieser Stackoverflow Frage aber auch noch den |slice Filter entdeckt, der den ganzen if-Block obsolet macht. Außerdem habe ich {{ category.seoBreadcrumb }} in {{ category.breadcrumb }} geändert, was mein „Sprechende-URL“-Problem gelöst hat: {% for part in category.breadcrumb|slice(1) %}{{ part|lower }}/{% endfor %}
Bei den Produkt-URLs habe ich einfach mal ganz schmutzig die Produkt-ID als Parameter mit einem ? an die URL gehangen. Mit dem Canonical sollte sich somit der Duplicate Content vermeiden lassen. {% for part in product.mainCategory.breadcrumb|slice(1) %}{{ part|lower }}/{% endfor %}{{ product.translated.name|lower }}?{{ product.id }}
… Nur der |lower Filter funktioniert bei beiden URL-Templates nicht ¯\_(ツ)_/¯