Skip to main content
Wo Events dich auf den Warenkorb reagieren lassen und Actions ihn ändern lassen, ändern Hooks, wie sich der Warenkorb selbst verhält: wie Zeilen gerendert werden, welche Daten sie tragen und was beim Add-to-cart passiert. Hooks liegen unter window.aftersell.cart.hooks.
Ein Hook ändert, was der Käufer sieht; eine Action ändert, was in seinem Warenkorb ist. Eine Gratisgeschenk-Zeile mit einer Transformation auszublenden lässt sie im Warenkorb und in der Gesamtsumme. Sie mit removeItem zu entfernen nimmt sie wirklich heraus.
Hooks sind Setup-Aufrufe und können daher sicher ganz am Anfang deines Scripts registriert werden, ohne auf ready() warten zu müssen. Registriere sie im Initialization-Script deines Warenkorbs (siehe Benutzerdefinierte Scripts).

Wie die Registrierung funktioniert

Jeder Hook ist eine register*-Methode. Du rufst sie mit deiner Funktion auf; sie gibt eine Unregister-Funktion zurück, die du aufrufen kannst, um deine zu entfernen.
Die Registrierung ist additiv, deine Funktion läuft also neben jeder anderen. Das ist wichtig, weil dein Script selten das einzige auf der Seite ist: Eine Abo-App, eine Bundle-App und das Theme selbst können alle gegen denselben Hook registrieren. Keine davon kann deine ersetzen, und nichts, was du registrierst, kann von dem, was nach dir lädt, stillschweigend verworfen werden. Ein Hook, der wirft oder keine Funktion ist, wird übersprungen; die restlichen laufen weiter, und der Warenkorb macht weiter. Eine defekte Integration kann Add-to-cart, den Abo-Picker oder die Sortierung nicht lahmlegen. Die Kehrseite ist, dass ein defekter Hook von dir still fehlschlägt: Nichts erreicht die Browser-Konsole. Siehe Debugging, um zu erfahren, wo diese Fehler doch auftauchen.

registerLineTransform

registerLineTransform(fn) läuft für jede Warenkorb-Zeile, bevor sie gerendert wird. Verwende es, um eine Zeile auszublenden oder ihre Darstellung zu ändern, ohne anzutasten, was tatsächlich im Warenkorb des Käufers ist. Die Funktion erhält eine schreibgeschützte Zeile plus Setter. Sie gibt eine Unregister-Funktion zurück.
Eine Transformation ändert nur, was gerendert wird. Sie kann Preis, Menge oder Zeilen-Identität nicht ändern. Verwende dafür die Actions.
Verwende es für: Gift-with-purchase- oder von Apps eingefügte Zeilen ausblenden, Abo-Zeilen umbenennen, rabattierte Artikel taggen, Bundle-Komponenten ausblenden, die der Käufer nicht einzeln verwalten sollte. setInternalProperties ist der Setter hinter der Bundle-Gruppierung: Die kanonischen Bundle-Properties auf jede Zeile zu stempeln ist der Weg, wie du die separaten Warenkorb-Zeilen einer Drittanbieter-App als einen Artikel rendern lässt. Siehe Bundle-Zeilen einer anderen App gruppieren.

registerLineComparator

Ein Comparator in derselben Form, die Array.prototype.sort erwartet. Er läuft nach Ausblenden und Umbenennen, sieht also die transformierten Zeilen.
Comparatoren kombinieren sich als Tie-Breaker: Der erste, der einen Nicht-Null-Wert zurückgibt, entscheidet dieses Paar, und die restlichen werden nur bei Gleichstand konsultiert. Gib 0 für Paare zurück, zu denen du keine Meinung hast. Genau das übergibt die Entscheidung an den nächsten Comparator, statt ihm eine Reihenfolge aufzuzwingen. Verwende es für: Abos oder hochwertige Artikel nach oben schweben lassen, Gratisgeschenke und Add-ons nach unten sinken lassen, ein gesponsertes Produkt an erster Stelle halten.

registerCartEnricher

registerCartEnricher(registration) holt zusätzliche Produkt- oder Variantendaten von der Shopify Storefront API und hängt sie an jede passende Warenkorb-Zeile unter line.metadata[id] an. Verwende es, um Metafelder, Tags oder alles andere anzuzeigen, was die Storefront API bereitstellt — ohne dass eine Code-Änderung von Aftersell nötig ist. Gibt eine Unregister-Funktion zurück. Wann immer der Warenkorb lädt oder sich ändert, holt Aftersell dein Fragment für jedes Produkt oder jede Variante im Warenkorb und hängt das Ergebnis an. Der Fetch ist nicht blockierend: Der Warenkorb rendert sofort und sendet erneut cart_updated, sobald die Daten ankommen. Ein langsames oder fehlschlagendes Fragment verzögert oder zerstört den Warenkorb nie.
Da die Anreicherung asynchron ist, schütze das Lesen immer, denn line.metadata.pricing ist undefined, bis der erste Fetch aufgelöst wird, und metadata selbst ist standardmäßig {}. Verwende es für: ein Metafeld auf jede Zeile ziehen (eine Lieferschätzung, eine Zutatenliste, ein „wird separat versendet“-Flag, ein Treue-Multiplikator) und es über einen Custom-Code-Block rendern. Siehe Metafeld-Daten auf Warenkorb-Zeilen anzeigen.
Mehrere Enricher koexistieren problemlos, da jede id ihr eigener Namespace ist und ihre Daten daher nie kollidieren.
Angereicherte Werte werden unverändert von der Storefront API zurückgegeben und sind nicht bereinigt. Rendere sie als Text, nicht als rohes HTML.

registerSubscriptionOptionsTransform

Blendet die auf einer Zeile angebotenen Selling Plans aus oder benennt sie um. Deine Funktion erhält schreibgeschützte Optionen plus Setter und gibt nichts zurück.
Setter statt einer zurückgegebenen Liste, damit mehrere Scripts koexistieren können. Würde dieser Hook ein Array zurückgeben, würde eine Transformation, die sich nur um einen Plan kümmert, natürlich options.filter(...) schreiben und auf dem Weg nach draußen stillschweigend die Pläne jeder anderen App löschen. Mit Settern kannst du nur deine eigenen Änderungen beschreiben: Patches werden pro Plan und pro Feld zusammengeführt, und der letzte Schreiber gewinnt einen echten Konflikt auf demselben Feld desselben Plans. Eine Transformation, die wirft, trägt nichts bei, und die anderen gelten weiterhin. Jede Transformation sieht die ursprünglichen Optionen, keine halb gepatchte Sicht — die Registrierungsreihenfolge ändert also nicht, was du liest.
Die Plan-Reihenfolge bleibt so, wie Shopify sie zurückgegeben hat, eine Transformation kann also nicht umsortieren. Um zu steuern, welcher Plan zuerst angeboten wird (und welchen der Einmalkauf-Upgrade-Button abonniert), verwende registerDefaultSubscriptionOptionSelector, das seine Auswahl nach vorne befördert.
Du kannst auch keinen Plan hinzufügen oder einen Preis ändern: discountPercent hat keinen Setter, denn ein Plan, den Shopify beim Checkout nicht honoriert, wäre nur ein gebrochenes Versprechen im Picker.

registerDefaultSubscriptionOptionSelector

Wähle, welcher Plan auf einer Zeile vorausgewählt ist. Gib eine Plan-id zurück, oder null, um zu passen.
Der erste Selector, der die id eines verfügbaren Plans zurückgibt, gewinnt — gib also null für die Zeilen zurück, die dich nicht interessieren, statt zu raten. Das übergibt die Entscheidung an den nächsten Selector, statt ihn zu überschreiben. Eine id, die zu keinem Plan auf der Zeile passt, wird wie null behandelt und passt ebenfalls, sodass eine veraltete id den Picker nicht leeren kann. Deine Funktion erhält (options, context), denselben context wie die Options-Transformation.

registerSkipAddToCartRule

Gib true zurück, um ein bestimmtes Produktformular normal zum Warenkorb hinzufügen zu lassen und Aftersell komplett zu umgehen. Das ist nützlich für ein Formular, das seinen eigenen Redirect oder eigene Verarbeitung braucht.
Jedes true überspringt — halte deine Regel also eng, passend zu den spezifischen Formularen, die dir gehören, und gib für alles andere false zurück. Regeln werden in Registrierungsreihenfolge ausgewertet und stoppen beim ersten true, also packe keine Nebenwirkungen hinein: Ob deine überhaupt läuft, hängt davon ab, was vor ihr registriert wurde.
Wenn du das Markup des Formulars kontrollierst, brauchst du gar keinen Hook: Füge dem <form> die Klasse aftersell-cart-skip-atc hinzu und Aftersell lässt es in Ruhe. Verwende diesen Hook, wenn du das Markup nicht bearbeiten kannst oder wenn die Entscheidung von etwas abhängt, das nur dein Code weiß.
Verwende es für: ein Vorbestell- oder Angebotsformular, das seinen eigenen Redirect braucht, den benutzerdefinierten Flow einer Abo-App, einen „Jetzt kaufen“-Button, der direkt zum Checkout gehen soll. Um das Abfangen stattdessen für die ganze Seite auszuschalten, verwende skip_add_to_cart_interceptor — bevorzuge aber diesen Hook, der auf die von dir benannten Formulare beschränkt ist.

Nächste Schritte

  • Cart-Objekt: die Struktur der Zeile, die eine Transformation erhält.
  • Events: alles, was du abonnieren kannst.
  • Actions: den Warenkorb lesen und ändern.
  • Use Cases: vollständige Lösungen für häufige Anforderungen.