Mit Events kannst du Code ausführen, wenn etwas im Warenkorb passiert. Sie liegen unter window.aftersell.cart.events.
Das Abonnieren ist ein Setup-Aufruf und daher am Anfang deines Scripts sicher, ohne auf ready() warten zu müssen.
events.on(event, handler) registriert einen Handler und gibt eine Funktion zurück, die ihn abmeldet:
events.once(event, handler): wird einmal ausgelöst und meldet sich dann selbst ab.
events.off(event, handler): entfernt einen bestimmten Handler.
Ein Handler, der wirft, wird isoliert und in der Konsole protokolliert; die anderen Handler laufen weiter.
Fast jeder Event-Bug lässt sich auf eine davon zurückführen.
Ändere den Warenkorb nicht ungeschützt aus cart_updated
Den Warenkorb innerhalb eines cart_updated-Handlers zu ändern löst erneut cart_updated aus. Wenn dieser Handler den Warenkorb wieder ändert, hast du eine Endlosschleife. Der Käufer sieht seinen Warenkorb flackern, während die Seite Shopify bombardiert.
Rufe nie bedingungslos eine Action aus cart_updated oder cart_loaded auf. Schütze sie mit einer Prüfung auf den Zustand, den du gleich erzeugst, sodass der zweite Durchlauf nichts tut.
Der Warenkorb gibt dir ein Sicherheitsnetz: Ein Update, das einen identischen Warenkorb erzeugt, sendet nichts, sodass ein Refetch, der nichts ändert, den Zyklus nicht neu startet. Das schützt dich vor versehentlichen No-op-Schleifen. Es schützt dich nicht vor einem Handler, der den Warenkorb tatsächlich jedes Mal ändert.
Behandle die Payload als schreibgeschützt
Jeder Handler eines Events erhält dasselbe Objekt. Es zu mutieren ändert, was die Handler nach deinem sehen, einschließlich der Handler, die zu anderen Apps im Shop gehören.
Um den Warenkorb tatsächlich zu ändern, verwende eine Action. Um zu ändern, wie Zeilen gerendert werden, verwende registerLineTransform.
Wird einmal ausgelöst, wenn der Warenkorb erstmals auf der Seite lädt. Die Payload ist das vollständige Cart-Objekt.
Verwende es für: alles, was gegen den Ausgangszustand des Warenkorbs laufen muss, etwa ein Gratisgeschenk abgleichen, ein Widget initialisieren oder den Warenkorb-Inhalt beim Seitenaufruf an Analytics melden.
cart_loaded wird für späte Abonnenten erneut abgespielt. Wenn du abonnierst, nachdem der Warenkorb bereits geladen ist, wird dein Handler sofort mit dem aktuellen Warenkorb aufgerufen. Die Abonnement-Reihenfolge spielt nie eine Rolle, du musst dir also keine Sorgen machen, ob dein Script schneller war als der Warenkorb.
Logik, die sowohl beim Seitenaufruf als auch bei jeder Änderung danach korrekt sein muss, sollte beide Events cart_loaded und cart_updated mit derselben Funktion abonnieren. Das ist das Standardmuster für „X mit dem Warenkorb synchron halten“.
Wird jedes Mal ausgelöst, wenn sich der Warenkorb-Inhalt nach dem ersten Laden ändert — sei es aus dem Drawer, durch deine eigenen Actions, durch das Theme oder durch eine andere App. Die Payload ist das vollständige Cart-Objekt.
Verwende es für: etwas außerhalb des Warenkorbs synchron halten, etwa eine eigene Gesamtsumme, einen Fortschrittsbalken, ein Header-Badge oder ein Analytics-Event bei jeder Änderung.
Ein Update, das einen identischen Warenkorb erzeugt, sendet nichts. Den Drawer erneut öffnen, zum Tab zurückwechseln oder ein Refetch, der denselben Inhalt zurückgibt, löst es nicht aus.
Wird ausgelöst, wenn eine neue Zeile im Warenkorb erscheint. Die Payload ist { item }, wobei item die Warenkorb-Zeile ist.
Verwende es für: Add-to-cart-Tracking in einem Drittanbieter-Analytics-Tool. Das ist der mit Abstand häufigste Einsatz des SDK. Siehe Add-to-cart tracken.
Zwei Dinge, die du über seine Herleitung wissen solltest:
Eine Mengenänderung ist kein Hinzufügen. Der Warenkorb ermittelt Hinzufügungen und Entfernungen durch Diffen der Zeilen, nicht der Mengen. Ein Käufer, der eine Zeile von 1 auf 3 erhöht, löst cart_updated aus, nicht item_added. Wenn du auch Mengenerhöhungen erfassen musst, vergleiche in einem cart_updated-Handler mit dem vorherigen Zustand.
Es wird auch nicht für Artikel ausgelöst, die beim Seitenaufruf bereits im Warenkorb waren; die kommen über cart_loaded an. Das gleichzeitige Hinzufügen mehrerer unterschiedlicher Produkte löst das Event einmal pro Zeile aus.
Wird ausgelöst, wenn eine Zeile aus dem Warenkorb verschwindet. Die Payload ist { item }, die Zeile wie sie kurz vor ihrem Verschwinden war — du kannst also weiterhin key, variantId und title lesen.
Verwende es für: etwas rückgängig machen, das du beim Hinzufügen getan hast, etwa ein Flag löschen, ein vom Käufer abgelehntes Angebot wieder einblenden oder Entfernungen an Analytics melden.
Derselbe Vorbehalt wie bei item_added: Eine Menge zu senken, ohne null zu erreichen, ist keine Entfernung.
cart_opened und cart_closed
Werden ausgelöst, wenn sich der Drawer öffnet und schließt. Keine Payload.
Verwende sie für: View-Tracking, ein Video oder Karussell hinter dem Drawer pausieren, eine Klasse auf der Seite umschalten.
Keines wird beim initialen Seitenaufruf ausgelöst, nur bei einem tatsächlichen Öffnen oder Schließen.
Wird ausgelöst, wenn der Käufer auf den Checkout-Button klickt, unmittelbar bevor der Browser navigiert. Keine Payload.
Verwende es für: Checkout-Intent-Tracking.
Du kannst den Checkout aus diesem Handler nicht abbrechen. Das Event ist eine Benachrichtigung, kein Gate; die Navigation passiert unabhängig davon, was dein Code tut. Halte den Handler schnell und synchron: Ein await oder ein langsamer Netzwerkaufruf wird möglicherweise nicht fertig, bevor die Seite entladen wird. Verwende navigator.sendBeacon für alles, was du zuverlässig senden musst.
Von außerhalb des SDK lauschen
Jedes Event wird auch als DOM-CustomEvent auf window gesendet, sodass du lauschen kannst, ohne window.aftersell.cart anzufassen. Das ist nützlich aus einer Theme-Datei, einer Drittanbieter-App oder einem Script, das unabhängig vom Warenkorb lädt.
Achte auf die Benennung: Der Bus verwendet snake_case, die DOM-Events verwenden kebab-case hinter einem aftersell:cart:-Präfix.
Die Payload kommt auf event.detail an und entspricht dem Cart-Objekt. Events werden auf window gesendet, sodass ein Listener überall auf der Seite sie empfängt. Der Warenkorb wird in einem Shadow Root gerendert, aber die Shadow-Grenze liegt nie im Pfad des Events. Jeder Versand klont die Payload, sodass ein Listener, der event.detail mutiert, niemand anderen beeinflussen kann, und ein Listener, der wirft, das SDK nicht stören kann.
cart-loaded wird im DOM nicht erneut abgespielt. Der Bus spielt cart_loaded für späte Abonnenten erneut ab, aber dieser Pfad umgeht den DOM-Versand — ein window.addEventListener('aftersell:cart:cart-loaded'), das registriert wird, nachdem der Warenkorb bereits geladen ist, wird also nie ausgelöst. Wenn die Ladereihenfolge deines Scripts nicht garantiert ist, verwende window.aftersell.cart.events.on('cart_loaded', …), das erneut abspielt, oder lausche zusätzlich auf aftersell:cart:cart-updated.
Shopify-Standard-Warenkorb-Events
Unabhängig davon veröffentlicht der Warenkorb Shopifys Standard-Warenkorb-Events auf document, wann immer er den Warenkorb ändert — Theme-Code und andere Apps können also auf Aftersells Mutationen genauso reagieren wie auf die des Themes:
Die Payload liegt nicht auf event.detail. detail trägt nur { source: 'aftersell' } — das Tag, mit dem der Warenkorb seine eigenen Events ignoriert, statt in eine Schleife zu geraten. Alles in der Tabelle oben wird direkt dem Event-Objekt zugewiesen — lies also event.action, nicht event.detail.action.
Jedes Event trägt außerdem ein promise, das Aftersell auflöst, wenn der zugrunde liegende Schreibvorgang abgeschlossen ist, entsprechend Shopifys Standard — warte darauf, löse es nicht selbst auf. Diese werden auf document gesendet und bubbeln, sodass ein window-Listener sie ebenfalls empfängt.
- Cart-Objekt: die vollständige Struktur der obigen Payloads.
- Actions: wie du den Warenkorb aus einem Handler änderst.
- Hooks: um zu ändern, wie der Warenkorb rendert, statt auf ihn zu reagieren.
- Use Cases: Analytics-Tracking, Gratisgeschenke und andere vollständige Beispiele.