> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Benutzerdefinierte Scripts

> Führe eigenes JavaScript im Aftersell Cart aus – mit den Script-Slots Initialization und On cart update.

Mit benutzerdefinierten Scripts kannst du dein eigenes JavaScript über das [Cart SDK](/de/aftersell/cart/sdk-overview) gegen den Warenkorb ausführen. Füge sie im Cart-Editor unter **Cart settings → Custom script** hinzu, wo ein Dropdown zwischen zwei Slots umschaltet: **Initialization** und **On cart update**.

Schreibe in diesen Editoren reines JavaScript, ohne `<script>`-Tags. **On cart update** hat eine **Reset to default**-Aktion, die die Starter-Vorlage wiederherstellt; **Initialization** nicht – bewahre also eine eigene Kopie auf, bevor du den Slot leerst.

<Note>
  Vieles, wofür Händler früher Scripts geschrieben haben, ist heute eine integrierte Einstellung. Sieh dir zuerst [Bevor du ein Script schreibst](/de/aftersell/cart/sdk-use-cases#before-you-write-a-script) an: Eine Einstellung funktioniert auch nach Cart-Redesigns weiter, dein Script möglicherweise nicht.
</Note>

<div id="which-slot-to-use">
  ## Welcher Slot ist der richtige
</div>

|                      | Initialization                                                                                                                                                                     | On cart update                                                        |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| **Läuft**            | Einmal, wenn der Warenkorb lädt.                                                                                                                                                   | Bei jeder Warenkorb-Änderung nach dem ersten Laden.                   |
| **Du schreibst**     | Das gesamte Script.                                                                                                                                                                | Nur den Handler-Body. Der `cart_updated`-Wrapper ist gesperrt.        |
| **Verwende ihn für** | Verhalten einmalig registrieren: [`configure`](/de/aftersell/cart/sdk-configure), [`events.on`](/de/aftersell/cart/sdk-events), [`hooks.register*`](/de/aftersell/cart/sdk-hooks). | Regeln, die bei jedem Warenkorb-Inhalt neu ausgewertet werden müssen. |
| **Beispiel**         | Gratisgeschenk-Zeilen mit einer Line-Transformation ausblenden.                                                                                                                    | Ein Gratisgeschenk mit einem Ausgabenschwellenwert synchron halten.   |

<div id="initialization">
  ## Initialization
</div>

Das **Initialization**-Script läuft **einmal, wenn der Warenkorb lädt**. Es ist dein Einstiegspunkt, um alles einzurichten: das Warenkorb-Verhalten konfigurieren, Events abonnieren und Hooks registrieren. Das [SDK](/de/aftersell/cart/sdk-overview) ist als `window.aftersell.cart` verfügbar.

Setup-Aufrufe, die du hier machst ([`configure(...)`](/de/aftersell/cart/sdk-configure), [`events.on(...)`](/de/aftersell/cart/sdk-events), [`hooks.*`](/de/aftersell/cart/sdk-hooks)), kannst du sicher am Anfang des Scripts aufrufen, noch bevor der Warenkorb vollständig hochgefahren ist; sie werden gepuffert und angewendet, sobald das passiert. Aktionen, die den Warenkorb lesen oder ändern (wie [`addItem`](/de/aftersell/cart/sdk-actions#additemvariantid-quantity) oder [`getCart`](/de/aftersell/cart/sdk-actions#getcart)), sollten innerhalb von [`ready()`](/de/aftersell/cart/sdk-overview#ready) oder eines Event-Handlers laufen.

Der Slot startet mit drei **auskommentierten** Beispielen – den Drawer bei jedem Hinzufügen öffnen, auf `cart_loaded` reagieren und Gratisgeschenk-Zeilen ausblenden –, sodass ein unverändertes Initialization-Script nichts tut. Kommentiere eines ein, um es auszuprobieren, oder ersetze sie.

Die natürliche Form für diesen Slot ist eine **einmalige Registrierung ohne beteiligte Events**: Registriere das Verhalten einmal und lass den Warenkorb es ab dann anwenden. Gratisgeschenk-Zeilen im Drawer auszublenden, ohne die Gesamtsumme zu ändern, ist das mitgelieferte Beispiel dafür:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerLineTransform((line) => {
  if (line.finalLinePrice === 0) line.setHidden(true);
});
```

[`registerLineTransform`](/de/aftersell/cart/sdk-hooks#registerlinetransform) läuft für jede Zeile, während sie gerendert wird, und `setHidden` betrifft nur die Anzeige – die Zeile bleibt also im Warenkorb und zählt weiterhin zur Gesamtsumme, sie wird nur nicht im Drawer angezeigt. Sieh dir [Warenkorb-Zeilen ausblenden und umbenennen](/de/aftersell/cart/sdk-use-case-hide-lines) an, um mehr über die Möglichkeiten einer Transformation zu erfahren.

Aktionen, die den Warenkorb lesen, gehören in `ready()`:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  console.log('Cart loaded with', state.itemCount, 'items');
});
```

Der Zugriff auf das DOM des Warenkorbs erfordert dieselbe Wartezeit und braucht [`shadowRoot`](/de/aftersell/cart/sdk-overview#shadowroot): Der Warenkorb wird innerhalb eines Shadow Root gerendert, sodass `document.querySelector` nichts im Drawer sehen kann.

<Tip>
  Du willst **vor** dem Laden des Warenkorbs nach Markt, Land oder Währung verzweigen? Lies stattdessen [`context`](/de/aftersell/cart/sdk-overview#context). Es ist synchron verfügbar, ganz ohne `ready()`, sodass du das Registrieren von Handlern für Käufer, auf die eine Regel nicht zutrifft, komplett überspringen kannst.
</Tip>

<div id="on-cart-update">
  ## On cart update
</div>

Das **On cart update**-Script läuft bei jeder Änderung des Warenkorbs. Es ist ein gesperrter Wrapper um ein `cart_updated`-Abonnement – du bearbeitest also nur den Body, und dein Code erhält den aktualisierten `cart`.

Dieser Slot ist für Regeln, die **bei jeder Warenkorb-Änderung neu ausgewertet** werden müssen. Ein Gratisgeschenk-Schwellenwert ist der klassische Fall (gib \$75 aus, erhalte eine Gratis-Tasche), weil die Antwort vom aktuellen Inhalt abhängt und dir nichts anderes mitteilen kann, wann er sich ändert:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('cart_updated', (cart) => {
  const GIFT_VARIANT_ID = 1234567890;
  const THRESHOLD = 7500;   // $75.00, in cents

  let giftLine = null;
  let subtotal = 0;
  (cart.items ?? []).forEach((line) => {
    if (line.variantId === GIFT_VARIANT_ID) giftLine = line;
    else subtotal += line.finalLinePrice;   // the gift itself never counts toward the threshold
  });

  const shouldHaveGift = subtotal >= THRESHOLD;
  const hasGift = Boolean(giftLine);

  // Bail when the cart already matches. This is the part that matters: adding or
  // removing an item fires cart_updated again, so without this check the handler
  // re-enters itself forever.
  if (shouldHaveGift === hasGift) return;

  if (shouldHaveGift) window.aftersell.cart.actions.addItem(GIFT_VARIANT_ID, 1);
  else window.aftersell.cart.actions.removeItem(giftLine.key);
});
```

<div id="keeping-the-cart-in-a-desired-state">
  ### Den Warenkorb in einem gewünschten Zustand halten
</div>

Die Zeile `if (shouldHaveGift === hasGift) return;` macht das Ganze sicher, und sie lässt sich auf jedes Script verallgemeinern, das den Warenkorb in einem gewünschten Zustand hält. Dieser Slot reagiert sowohl auf Warenkorb-Änderungen als auch verursacht sie, sodass jedes `addItem` oder `removeItem` ihn erneut auslöst. Beschreibe den Zustand, den du willst, vergleiche ihn mit dem Zustand, den du hast, und kehre frühzeitig zurück, wenn sie bereits übereinstimmen – so konvergiert der Handler nach einem Durchlauf, statt in eine Schleife zu geraten. Sieh dir [die zwei Regeln](/de/aftersell/cart/sdk-events#the-two-rules) an, um die ungeschützte Variante zu sehen, die du vermeiden solltest, und warum die Payload schreibgeschützt ist.

In einem langsameren Shop lohnt sich außerdem ein In-Flight-Flag auf Modulebene, damit zwei schnelle Änderungen nicht beide ein Hinzufügen starten können, bevor das erste abgeschlossen ist.

<Note>
  `cart_updated` wird nur bei Änderungen **nach** dem ersten Laden ausgelöst ([Event-Timing](/de/aftersell/cart/sdk-events#cart_updated)), sodass ein Script in diesem Slot einen Warenkorb, der beim Laden der Seite bereits qualifiziert ist, nicht abgleicht. Für eine Version, die beides abdeckt, abonniere `cart_loaded` und `cart_updated` mit derselben Funktion aus dem **Initialization**-Slot. Siehe [Ein Gratisgeschenk ab einem Schwellenwert automatisch hinzufügen](/de/aftersell/cart/sdk-use-case-free-gift).
</Note>

<div id="when-a-script-breaks">
  ## Wenn ein Script fehlschlägt
</div>

Jeder Slot läuft in seiner eigenen Sandbox, sodass ein defektes **Initialization**-Script die Ausführung von **On cart update** nicht verhindern kann – und keines von beiden kann den Warenkorb selbst zum Absturz bringen.

Innerhalb eines Slots **stoppt die Ausführung jedoch beim ersten Fehler**. Alles unterhalb dieser Zeile wird übersprungen, was bedeutet, dass jedes `configure`, `events.on` oder `hooks.register*` weiter unten nie registriert wird. Das ist die übliche Erklärung für „mein Handler wird nie ausgelöst“, obwohl der Code richtig aussieht.

Der Warenkorb nennt die fehlerhafte Zeile in der Browser-Konsole, und jeder Slot läuft unter seinem eigenen Dateinamen (`aftersell-cart-init.js` und `aftersell-cart-cart-update.js`), sodass du beide im Sources-Panel der DevTools öffnen und Breakpoints setzen kannst. Siehe [Debugging](/de/aftersell/cart/sdk-overview#debugging) für die genauen Meldungen und für den Debug-Kanal, der Hook-Fehler abfängt, die nicht in der Konsole erscheinen.

Da `cart_loaded` [für späte Abonnenten erneut abgespielt wird](/de/aftersell/cart/sdk-events#cart_loaded), spielt die Registrierungsreihenfolge nie eine Rolle. Die sicherste Struktur ist, zuerst alles zu registrieren und die riskante Arbeit innerhalb von Handlern zu erledigen, wo ein Throw auf diesen Handler beschränkt bleibt.

<div id="where-to-go-next">
  ## Nächste Schritte
</div>

* **[Cart SDK](/de/aftersell/cart/sdk-overview)**: Benutzerdefinierte Scripts sind der Weg, SDK-Code auszuführen. Sieh dir die Referenzen zu [configure](/de/aftersell/cart/sdk-configure), [Events](/de/aftersell/cart/sdk-events), [Actions](/de/aftersell/cart/sdk-actions) und [Hooks](/de/aftersell/cart/sdk-hooks) für die gesamte Oberfläche an, das [Cart-Objekt](/de/aftersell/cart/sdk-cart-object) für die Struktur dessen, was Handler erhalten, und die [Use Cases](/de/aftersell/cart/sdk-use-cases) für fertige Snippets.
* **[Custom-Code-Blöcke](/de/aftersell/cart/custom-code-blocks)**: zum Hinzufügen von Markup zum Warenkorb. Beachte, dass der HTML-Modus des Custom-Code-Blocks **kein** JavaScript ausführt; verwende für Logik benutzerdefinierte Scripts (oder den React-Modus des Blocks).
