SEO URL Generierung mit Varianteneigenschaft als Suffix

Hallo zusammen,

ich sitze jetzt schon länger an dem Problem, dass ich die SEO URLs nicht richtig generiert bekomme.

Die URL soll für Produkte mit Varianten so aussehen:

https://domain.de/produkt-name-in-lowercase-xxl (Der “xxl”-Suffix soll hierbei die Varianteneigenschaft sein)

Bei Produkten ohne Varianten, soll dieser Suffix natürlich nicht vorkommen.

Ich habe jetzt schon mehrere Möglichkeiten ausprobiert, keine funktioniert jedoch und er generiert wieder abstrakte URLs.

Meine Ansatz, der auch laut twig gültig sein sollte:

Bei {{ product.variation }} handelt es sich um ein array, ich bin also mit einer for-schleife wie folgt drüber:

{{ product.translated.name|lower }}{% if product.variation %}{% for variation in product.variation %}-{{ variation.option }}{% endfor %}{% endif %}

Ich habe es aber auch mal so probiert, da in dem Array sowieso nur ein item vorhanden ist:

{{ product.translated.name|lower }}{% if product.variation %}-{{ (product.variation|first).option }}{% endif %}

auch

{{ product.translated.name|lower }}-{{ product.variation }}

wie in der Administration vorgeschlagen, funktioniert natürlich nicht, da ein Array nicht in ein String umgewandelt werden kann.

Hat jemand eine Idee, was ich falsch mache?

LG Luca

Gibt es kein product.variation.name oder sowas, der gleich schon ein string ist?

Nein leider nicht, der string wird über .option im Array angesprochen. Das Array ist das Problem bei der ganzen Geschichte.

 

Dieses Problem ist schon länger bekannt und wurde noch nicht behoben:

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.

Wie habt Ihr die Sache gelöst?

Moin @littleAmused ,

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…

  • Du holst dir folgendes Plugin SEO Professional | SEO Optimierung | Erweiterungen | Shopware Store, Dreischild hat genau das gemacht, sodass Du Varianten SEO URLs richtig generieren kannst. Support ist auch super.

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:

{% sw_extends ‚@Storefront/storefront/page/product-detail/meta.html.twig‘ %}

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…

Ich hoffe ich konnte Dir etwas weiterhelfen.

VG Luca

2 „Gefällt mir“

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.

Beste Grüße, LA

@littleAmused sehr gerne.

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.

bin/console dal:refresh:index && bin/console cache:clear

LG Luca

Hallo Luca,

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 ¯\_(ツ)_/¯

Beste Grüße, LA