Met events kun je code draaien wanneer er iets gebeurt in de winkelwagen. Ze staan onder window.aftersell.cart.events.
Abonneren is een set-up-aanroep, dus veilig bovenaan je script, zonder dat je op ready() hoeft te wachten.
events.on(event, handler) registreert een handler en geeft een functie terug die het abonnement opzegt:
events.once(event, handler): gaat één keer af en schrijft zichzelf daarna uit.
events.off(event, handler): verwijdert een specifieke handler.
Een handler die een fout gooit wordt geïsoleerd en naar de console gelogd; de andere handlers draaien gewoon door.
Bijna elke event-bug is terug te voeren op een van deze.
Wijzig de winkelwagen niet vanuit cart_updated zonder guard
De winkelwagen wijzigen binnen een cart_updated-handler laat cart_updated opnieuw afgaan. Als die handler de winkelwagen opnieuw wijzigt, heb je een oneindige loop. De shopper ziet zijn winkelwagen wild heen en weer gaan terwijl de pagina Shopify bestookt.
Roep nooit onvoorwaardelijk een action aan vanuit cart_updated of cart_loaded. Beveilig hem met een check op de staat die je gaat creëren, zodat de tweede doorloop niets doet.
De winkelwagen geeft je wel één vangnet: een update die een identieke winkelwagen oplevert stuurt niets uit, dus een refetch die niets verandert start de cyclus niet opnieuw. Dat beschermt je tegen onbedoelde no-op-loops. Het beschermt je niet tegen een handler die de winkelwagen elke keer echt verandert.
Behandel de payload als alleen-lezen
Elke handler voor één event ontvangt hetzelfde object. Muteren ervan verandert wat de handlers na de jouwe zien, inclusief handlers van andere apps in de winkel.
Om de winkelwagen echt te wijzigen, gebruik je een action. Om te wijzigen hoe regels renderen, gebruik je registerLineTransform.
Gaat één keer af, wanneer de winkelwagen voor het eerst op de pagina laadt. De payload is het volledige cart-object.
Gebruik het voor: alles wat tegen de startstaat van de winkelwagen moet draaien, zoals een gratis geschenk afstemmen, een widget initialiseren of de winkelwageninhoud bij page load rapporteren aan analytics.
cart_loaded wordt herafgespeeld voor late abonnees. Als je je abonneert nadat de winkelwagen al is geladen, wordt je handler direct aangeroepen met de huidige winkelwagen. De volgorde van abonneren maakt nooit uit, dus je hoeft je geen zorgen te maken of je script sneller was dan de winkelwagen.
Logica die zowel bij page load als bij elke wijziging daarna correct moet zijn, moet zich met dezelfde functie op zowel cart_loaded als cart_updated abonneren. Dat is het standaardpatroon voor “houd X in sync met de winkelwagen”.
Gaat elke keer af dat de inhoud van de winkelwagen verandert na de eerste load, of dat nu via de drawer is, via je eigen actions, via het thema of via een andere app. De payload is het volledige cart-object.
Gebruik het voor: iets buiten de winkelwagen in sync houden, zoals een eigen totaal, een voortgangsbalk, een headerbadge of een analytics-event bij elke wijziging.
Een update die een identieke winkelwagen oplevert stuurt niets uit. De drawer opnieuw openen, terugschakelen naar het tabblad of een refetch die dezelfde inhoud teruggeeft, laat het niet afgaan.
Gaat af wanneer er een nieuwe regel in de winkelwagen verschijnt. De payload is { item }, waarbij item de winkelwagenregel is.
Gebruik het voor: add-to-cart-tracking in een externe analytics-tool. Dit is verreweg de meest voorkomende toepassing van de SDK. Zie add-to-cart tracken.
Twee dingen om te weten over hoe het wordt afgeleid:
Een aantalswijziging is geen toevoeging. De winkelwagen bepaalt toevoegingen en verwijderingen door regels te diffen, niet aantallen. Een shopper die een regel van 1 naar 3 verhoogt, triggert cart_updated, niet item_added. Als je ook aantalverhogingen wilt opvangen, vergelijk dan met de vorige staat in een cart_updated-handler.
Het gaat ook niet af voor artikelen die al in de winkelwagen zaten toen de pagina laadde; die komen binnen via cart_loaded. Meerdere verschillende producten tegelijk toevoegen laat het event één keer per regel afgaan.
Gaat af wanneer een regel uit de winkelwagen verdwijnt. De payload is { item }, de regel zoals hij was net voordat hij verdween, dus je kunt nog steeds zijn key, variantId en title lezen.
Gebruik het voor: iets terugdraaien wat je bij het toevoegen deed, zoals een vlag wissen, een aanbieding die de shopper afsloeg opnieuw tonen, of verwijderingen rapporteren aan analytics.
Dezelfde kanttekening als bij item_added: een aantal verlagen zonder nul te raken is geen verwijdering.
cart_opened en cart_closed
Gaan af wanneer de drawer opent en sluit. Geen payload.
Gebruik het voor: view-tracking, een video of carrousel achter de drawer pauzeren, een class op de pagina togglen.
Geen van beide gaat af bij de initiële page load, alleen bij een daadwerkelijk openen of sluiten.
Gaat af wanneer de shopper op de checkout-knop klikt, onmiddellijk voordat de browser navigeert. Geen payload.
Gebruik het voor: tracking van checkout-intentie.
Je kunt de checkout niet annuleren vanuit deze handler. Het event is een notificatie, geen poort; navigatie vindt plaats ongeacht wat je code doet. Houd de handler snel en synchroon: een await of een trage netwerkcall is mogelijk niet klaar voordat de pagina unloadt. Gebruik navigator.sendBeacon voor alles wat je betrouwbaar moet versturen.
Luisteren van buiten de SDK
Elk event wordt ook gedispatcht als een DOM-CustomEvent op window, dus je kunt luisteren zonder window.aftersell.cart aan te raken. Dat is handig vanuit een themabestand, een externe app of een script dat onafhankelijk van de winkelwagen laadt.
Let op de naamgeving: de bus gebruikt snake_case, de DOM-events gebruiken kebab-case achter een aftersell:cart:-prefix.
De payload komt binnen op event.detail en komt overeen met het cart-object. Events worden gedispatcht op window, dus een listener waar dan ook op de pagina ontvangt ze. De winkelwagen rendert in een shadow root, maar de shadow-grens zit nooit in het pad van het event. Elke dispatch kloont de payload, dus een listener die event.detail muteert kan niemand anders beïnvloeden, en een listener die een fout gooit kan de SDK niet verstoren.
cart-loaded wordt niet herafgespeeld op de DOM. De bus speelt cart_loaded opnieuw af voor late abonnees, maar dat pad omzeilt de DOM-dispatch, dus een window.addEventListener('aftersell:cart:cart-loaded') geregistreerd nadat de winkelwagen al is geladen zal nooit afgaan. Als de laadvolgorde van je script niet gegarandeerd is, gebruik dan window.aftersell.cart.events.on('cart_loaded', …), die wel herafspeelt, of luister ook naar aftersell:cart:cart-updated.
Shopify standaard cart-events
Daarnaast publiceert de winkelwagen Shopify’s standaard cart-events op document telkens wanneer hij de winkelwagen wijzigt, zodat themacode en andere apps op Aftersell’s mutaties kunnen reageren op dezelfde manier als op die van het thema:
De payload zit niet op event.detail. detail bevat alleen { source: 'aftersell' } — de tag die de winkelwagen gebruikt om zijn eigen events te negeren in plaats van te loopen. Alles in de tabel hierboven wordt direct op het event-object gezet, dus lees event.action, niet event.detail.action.
Elk event draagt ook een promise die Aftersell settelt wanneer de onderliggende write landt, conform Shopify’s standaard — await hem, resolve hem niet. Deze worden gedispatcht op document en bubbelen, dus een window-listener ontvangt ze ook.
- Cart-object: de volledige vorm van de payloads hierboven.
- Actions: hoe je de winkelwagen wijzigt vanuit een handler.
- Hooks: om te wijzigen hoe de winkelwagen rendert, in plaats van erop te reageren.
- Use cases: analytics-tracking, gratis geschenken en andere complete voorbeelden.