Breadcrumbs und ItemList für Shopify einrichten.
Zwei Snippets, die deine Collection- und Produktseiten maschinenlesbar machen: sichtbare Breadcrumbs mit BreadcrumbList-Markup plus ItemList für Collections. Gehört zum Werkstatt-Artikel „Shopify: Breadcrumbs und ItemList Markup für Collections nachrüsten".
1. Was du hier einbaust
Zwei Liquid-Snippets im Theme: breadcrumbs.liquid rendert den sichtbaren Pfad und das BreadcrumbList-Markup aus einer Logik, collection-itemlist.liquid meldet Google deine Collections als geordnete Produktlisten.
Breadcrumb-Pfade in den Suchergebnissen, Struktursignale für Sitelinks und KI-Systeme.
20 bis 30 Minuten, ohne App, ohne Abo, ohne Theme-Wechsel.
Du arbeitest im Theme-Duplikat. Ein Klick auf das alte Theme macht alles rückgängig.
Nach Theme-Updates kurz prüfen, ob Snippets und Einbindung noch da sind.
2. Voraussetzungen
Zugriff auf Onlineshop, Themes mit der Berechtigung, Code zu bearbeiten.
Pflicht vor dem ersten Edit: Drei-Punkte-Menü am Theme, „Duplizieren". Gearbeitet wird nur im Duplikat.
Deine Produkte hängen in Collections, die als Kategorien taugen. Reine Sale-Sammlungen zählen nicht.
Für Pfad-Kontrolle und Kategorie-Ebenen: custom.primary_collection an Produkten, custom.parent_collection an Collections (Schritt „Anpassen").
3. Einrichtung Schritt für Schritt
-
Theme duplizieren und Code-Editor öffnen
Im Shopify-Admin unter Onlineshop, Themes: Drei-Punkte-Menü, erst
Duplizieren, dann im DuplikatCode bearbeiten. Veröffentlicht wird erst nach der Validierung am Ende. -
breadcrumbs.liquid anlegen
Im Code-Editor unter Snippets eine neue Datei
breadcrumbs.liquidanlegen und diesen Code einfügen:snippets/breadcrumbs.liquid{% unless template == 'index' %} {%- liquid assign crumb_excluded = 'all,frontpage,sale,sales,angebot,angebote,aktion,aktionen,deals,bestseller,neuheiten,new,featured,black-friday,cyber-monday' | split: ',' assign crumb_collection = blank assign crumb_parent = blank assign crumb_grandparent = blank if template contains 'product' assign primary = product.metafields.custom.primary_collection.value if primary.first != blank assign primary = primary.first endif if primary != blank unless crumb_excluded contains primary.handle assign crumb_collection = primary endunless endif if crumb_collection == blank and collection unless crumb_excluded contains collection.handle assign crumb_collection = collection endunless endif if crumb_collection == blank for c in product.collections unless crumb_excluded contains c.handle assign c_parent = c.metafields.custom.parent_collection.value if c_parent.first != blank assign c_parent = c_parent.first endif if c_parent != blank assign crumb_collection = c break endif endunless endfor endif if crumb_collection == blank for c in product.collections unless crumb_excluded contains c.handle assign crumb_collection = c break endunless endfor endif elsif template contains 'collection' and collection assign crumb_collection = collection endif if crumb_collection != blank assign p = crumb_collection.metafields.custom.parent_collection.value if p.first != blank assign p = p.first endif if p != blank and p.handle != crumb_collection.handle unless crumb_excluded contains p.handle assign crumb_parent = p endunless endif endif if crumb_parent != blank assign gp = crumb_parent.metafields.custom.parent_collection.value if gp.first != blank assign gp = gp.first endif if gp != blank and gp.handle != crumb_parent.handle and gp.handle != crumb_collection.handle unless crumb_excluded contains gp.handle assign crumb_grandparent = gp endunless endif endif -%} <nav class="breadcrumbs" aria-label="Breadcrumb"> <a href="{{ routes.root_url }}">Start</a> {% if crumb_grandparent != blank %} <span aria-hidden="true">›</span> <a href="{{ crumb_grandparent.url }}">{{ crumb_grandparent.title }}</a> {% endif %} {% if crumb_parent != blank %} <span aria-hidden="true">›</span> <a href="{{ crumb_parent.url }}">{{ crumb_parent.title }}</a> {% endif %} {% if template contains 'product' %} {% if crumb_collection != blank %} <span aria-hidden="true">›</span> <a href="{{ crumb_collection.url }}">{{ crumb_collection.title }}</a> {% endif %} <span aria-hidden="true">›</span> <span aria-current="page">{{ product.title }}</span> {% elsif template contains 'collection' and collection %} <span aria-hidden="true">›</span> <span aria-current="page">{{ collection.title }}</span> {% endif %} </nav> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Start", "item": "{{ shop.url }}" } {%- assign pos = 1 -%} {%- if crumb_grandparent != blank -%} {%- assign pos = pos | plus: 1 -%} ,{ "@type": "ListItem", "position": {{ pos }}, "name": {{ crumb_grandparent.title | json }}, "item": "{{ shop.url }}{{ crumb_grandparent.url }}" } {%- endif -%} {%- if crumb_parent != blank -%} {%- assign pos = pos | plus: 1 -%} ,{ "@type": "ListItem", "position": {{ pos }}, "name": {{ crumb_parent.title | json }}, "item": "{{ shop.url }}{{ crumb_parent.url }}" } {%- endif -%} {%- if template contains 'product' -%} {%- if crumb_collection != blank -%} {%- assign pos = pos | plus: 1 -%} ,{ "@type": "ListItem", "position": {{ pos }}, "name": {{ crumb_collection.title | json }}, "item": "{{ shop.url }}{{ crumb_collection.url }}" } {%- endif -%} {%- assign pos = pos | plus: 1 -%} ,{ "@type": "ListItem", "position": {{ pos }}, "name": {{ product.title | json }}, "item": "{{ shop.url }}{{ product.url }}" } {%- elsif template contains 'collection' and collection -%} {%- assign pos = pos | plus: 1 -%} ,{ "@type": "ListItem", "position": {{ pos }}, "name": {{ collection.title | json }}, "item": "{{ shop.url }}{{ collection.url }}" } {%- endif %} ] } </script> {% endunless %} -
collection-itemlist.liquid anlegen
Zweite Datei, gleiche Stelle:
collection-itemlist.liquid.snippets/collection-itemlist.liquid{% if template contains 'collection' and collection %} <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "ItemList", "name": {{ collection.title | json }}, "numberOfItems": {{ collection.products_count }}, "itemListElement": [ {%- for product in collection.products -%} { "@type": "ListItem", "position": {{ forloop.index }}, "url": "{{ shop.url }}{{ product.url }}" }{%- unless forloop.last -%},{%- endunless -%} {%- endfor %} ] } </script> {% endif %} -
Alte Theme-Breadcrumbs finden und ersetzen
Viele Themes bringen eigene Breadcrumbs mit, oft ohne Kategorie-Ebene und ohne Markup. Bleiben sie drin, hast du zwei Pfade auf der Seite.
Der schnellste Weg: Öffne layout/theme.liquid und such mit Strg+F nach „breadcrumb". Bei vielen Themes wird der Pfad genau dort gerendert, zwischen Header und
{{ content_for_layout }}, oft eingepackt in eine Bedingung wie{% if settings.breadcrumbs_enabled %}. Ersetze den alten render-Aufruf mitsamt Parametern (etwaseparator, unser Snippet ignoriert sie) und inklusive if-Rahmen durch{% render 'breadcrumbs' %}. Umgebende Wrapper-Divs lässt du stehen, die zentrieren auf Content-Breite. Damit sind Ersetzen und Einbau in einem erledigt, Schritt 5 entfällt für dich.Wird die Suche in theme.liquid nicht fündig, rendert dein Theme die Breadcrumbs in einer Section oder einem Snippet:
- Globale Code-Suche (Lupensymbol) nach „breadcrumb" und „crumb". Achtung Singular-Falle: Theme-Dateien heißen gern
breadcrumb.liquid, deine neue Dateibreadcrumbs.liquid. - Frontend-Trick: Rechtsklick auf die sichtbare Breadcrumb im Shop, „Untersuchen", Klassennamen ablesen, danach im Code suchen.
- Ersetzen statt löschen: Entscheidend ist die Aufruf-Zeile, meist
{% render 'breadcrumb' %}oder{% include 'breadcrumb' %}. Diese Zeile tauschst du gegen den neuen Aufruf aus Schritt 5. Die alte Datei kann liegen bleiben, ohne Aufruf ist sie stumm.
Nicht fündig oder unsicher? Kopiere theme.liquid und die Treffer deiner Suche in Claude oder ChatGPT und frag: „Wo werden in diesem Shopify-Theme die Breadcrumbs gerendert, und wie ersetze ich sie gegen {% render 'breadcrumbs' %}?" Mit dem Theme-Duplikat kann dabei nichts passieren. - Globale Code-Suche (Lupensymbol) nach „breadcrumb" und „crumb". Achtung Singular-Falle: Theme-Dateien heißen gern
-
Breadcrumbs einbinden (nur, wenn dein Theme keine hatte)
Hast du in Schritt 4 den Block in theme.liquid ersetzt, bist du hier fertig. Sonst: Öffne layout/theme.liquid, such die Zeile
{{ content_for_layout }}und setz den Aufruf direkt davor:layout/theme.liquid{% render 'breadcrumbs' %}Damit erscheinen die Breadcrumbs auf jeder Seite über dem Inhalt, auch auf Produktseiten. Auf der Startseite blendet sich das Snippet selbst aus. Rendert dein Theme zwischen Header und Inhalt noch Banner-Sections, setz den Aufruf unter diese Zeilen.
-
ItemList ins Collection-Template
Die zuständige Datei heißt je nach Theme anders. So findest du deine:
- templates/collection.json öffnen: Im Abschnitt
"main"steht unter"type"der Section-Name, bei Dawn etwamain-collection-product-grid. Das ist deine Datei im sections-Ordner. - Kein collection.json? Dann arbeitet dein Theme mit
templates/collection.liquiddirekt, der Aufruf gehört dorthin. - Zur Not: Code-Suche nach
collection.products. Die Datei mit der Produktschleife ist die richtige.
Dort ans Dateiende, außerhalb aller Schleifen:
Section-Datei deiner Collection{% render 'collection-itemlist' %} - templates/collection.json öffnen: Im Abschnitt
4. Anpassen: Ausschlussliste, Metafeld, Styling
Ausschlussliste: Die Liste crumb_excluded ganz oben in breadcrumbs.liquid hält Sale-, Aktions- und Bestseller-Collections aus dem Pfad heraus. Ergänze die Handles deiner eigenen Aktionsflächen, bevor du live gehst. Handles findest du in der URL der Collection.
Metafelder für Pfad-Kontrolle und Kategorie-Ebenen (optional): Beide legst du unter Einstellungen, Benutzerdefinierte Daten an, jeweils als Collection-Referenz vom Typ „Eine Collection". Die exakten Namespaces sind entscheidend, genau die liest das Snippet:
- Produkte, „Primary Collection" (ergibt
custom.primary_collection): steuert auf Produktseiten, welche Collection im Pfad steht. Erste Wahl vor URL-Kontext und automatischer Auswahl. Ohne Eintrag bevorzugt das Snippet automatisch Collections mit gepflegter Oberkategorie vor Themen-Collections. - Collections, „Parent Collection" (ergibt
custom.parent_collection): steuert, welche Oberkategorie vor einer Collection steht. Bei jeder Unterkategorie die Oberkategorie auswählen, das Snippet baut die Kette bis zu zwei Eltern-Ebenen: Start, Kaffee, Espressobohnen, Produktname.
Ohne gepflegte Metafelder zeigt das Snippet eine Ebene und funktioniert trotzdem. Der Schalter „Storefront API access" in der Metafeld-Definition ist für Liquid ohne Bedeutung.
Produktname am Ende (Geschmackssache): Bei langen Produktnamen kannst du den Titel aus der sichtbaren Nav entfernen, dafür löschst du im product-Zweig die zwei Zeilen mit product.title (Trenner-Span und aria-current-Span). Das BreadcrumbList-Markup bleibt unverändert, es beschreibt weiterhin die Position der Seite.
Styling: Die sichtbaren Breadcrumbs kommen unformatiert an, direkt nach dem Einbau sehen sie nach rohem HTML aus. Das ist normal: Das Snippet bringt bewusst kein CSS mit, und wenn du einen Theme-Block ersetzt hast, stylte das alte Theme-CSS nur die alten Klassen. Dieser Startpunkt gehört in den Theme-Editor unter Theme-Einstellungen, Benutzerdefiniertes CSS:
.breadcrumbs {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
max-width: var(--page-width, 1200px);
margin: 0 auto;
padding: 14px 20px;
font-size: 0.875rem;
line-height: 1.4;
color: rgba(0, 0, 0, 0.55);
}
.breadcrumbs a {
color: inherit;
text-decoration: none;
}
.breadcrumbs a:hover {
text-decoration: underline;
}
.breadcrumbs span[aria-current="page"] {
color: rgba(0, 0, 0, 0.85);
}Farben und Schriftgröße ans Theme angleichen. Leitplanke: kleine Schrift, dezente Farbe, 16 bis 24 Pixel Abstand nach oben und unten. Orientieren, nicht dominieren. Und: nicht mobil ausblenden, Google bewertet die mobile Ansicht.
5. Validieren, dann veröffentlichen
-
Rich Results Test
Öffne eine Collection- und eine Produktseite der Duplikat-Vorschau im Google Rich Results Test. Erwartung: BreadcrumbList wird ohne Fehler erkannt.
-
Schema-Validator
Das ItemList-Markup prüfst du im Schema.org Validator, es erzeugt kein eigenes Rich Result und taucht deshalb im Rich Results Test nicht auf.
-
Klick-Check und Veröffentlichung
Alle Breadcrumb-Links einmal durchklicken: Jeder muss auf eine kanonische URL führen, keine /collections/-Produktpfade. Danach das Duplikat veröffentlichen und in der Search Console unter Verbesserungen beobachten, ob der Breadcrumb-Bericht nach einigen Tagen Seiten aufnimmt.
6. Troubleshooting
Auf der Seite stehen zwei Breadcrumb-Zeilen
render 'breadcrumb' und include 'breadcrumb' und entferne den alten Aufruf. Prüfe auch Sections, manche Themes rendern Breadcrumbs innerhalb der Seiten-Section statt im Layout.Im Pfad steht „Sale" oder „Bestseller"
Der Rich Results Test findet kein BreadcrumbList
application/ld+json suchen: Steht das Markup drin, aber der Test meckert, liegt es meist an einem Syntaxfehler durch nachträgliche Änderungen am Snippet.Ich finde die Collection-Section nicht
Die Breadcrumbs sehen kaputt oder deplatziert aus
.breadcrumbs in deinem Theme-CSS oder im Custom-CSS-Feld des Theme-Editors.Nach einem Theme-Update ist alles weg
7. Abschluss-Checkliste
Erst veröffentlichen, wenn jeder Punkt sitzt.
- Theme dupliziert, gearbeitet wird im Duplikat.
- breadcrumbs.liquid angelegt.
- collection-itemlist.liquid angelegt.
- Ausschlussliste um eigene Aktions-Handles ergänzt.
- Alte Theme-Breadcrumbs gefunden und Aufruf entfernt beziehungsweise Block ersetzt.
- Breadcrumbs in theme.liquid vor content_for_layout aktiv (ersetzt oder neu gesetzt).
- ItemList in der Collection-Section eingebunden.
- Rich Results Test grün für Collection- und Produktseite.
- ItemList im Schema-Validator geprüft.
- Alle Breadcrumb-Links führen auf kanonische URLs.
- Duplikat veröffentlicht, Search-Console-Bericht im Blick.
Du willst mehr als Breadcrumbs?
Struktur, Produktdaten, interne Verlinkung, AI-Sichtbarkeit: Wenn dein Shop mehr Substanz vertragen kann, schau ich gern einmal drauf. 30 Minuten, direkt mit mir.
Shop-Audit sichern© 2026 Oliver Dahm · SEO- und AI-Consultant für Online-Shops · oliverdahm.de