> ## 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.

# Überblick

> Wie das Aftersell Cart SDK funktioniert: der globale Einstiegspunkt, die vier Teile der API, wann es lädt und wie du sicher Code dagegen ausführst.

Das **Cart SDK** ist eine JavaScript-API für den Aftersell Cart in deinem Storefront. Es lässt dich ändern, wie sich der Warenkorb verhält, auf das reagieren, was Käufer tun, und den Inhalt des Warenkorbs per Code lesen oder ändern.

Du führst SDK-Code über [benutzerdefinierte Scripts](/de/aftersell/cart/custom-scripts) aus, oder über den React-Modus eines [Custom-Code-Blocks](/de/aftersell/cart/custom-code-blocks) für einen Block, der seine eigene UI rendert.

<Note>
  Vieles, was Händler vom SDK verlangen, ist bereits eine Einstellung. Prüfe vor dem Schreiben eines Scripts, ob ein [Cart-Block](/de/aftersell/cart/blocks-overview), [Bedingungen nach Markt/Land/Währung](/de/aftersell/cart/blocks-overview#show-or-hide-by-market-country-or-currency) oder eine [Cart-Einstellung](/de/aftersell/cart/cart-settings) es bereits erledigt. Die funktionieren auch nach Cart-Redesigns weiter, dein Script möglicherweise nicht.
</Note>

<div id="the-global-entry-point">
  ## Der globale Einstiegspunkt
</div>

Alles hängt an einem Global:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart
```

<Note>
  **Jedes Snippet in diesen Docs schreibt `window.aftersell.cart` vollständig aus**, sodass jedes für sich funktioniert, wenn du es einfügst. Es einmal zu aliasen (`const cart = window.aftersell.cart;`) und ab dann `cart` zu verwenden ist ebenfalls völlig valide und sogar sicher, bevor der Warenkorb lädt. Denk nur daran, diese Zeile einzufügen, wenn du ein Snippet kürzt, denn ein nacktes `cart` allein wirft `cart is not defined`.
</Note>

Vier Teile erledigen die Arbeit:

<Columns cols={2}>
  <Card title="Configure" icon="sliders" href="/de/aftersell/cart/sdk-configure">
    Lege fest, wie sich der Warenkorb verhält: wann sich der Drawer öffnet, wie Geld formatiert wird, ob Aftersell Add-to-cart abfängt.
  </Card>

  <Card title="Events" icon="tower-broadcast" href="/de/aftersell/cart/sdk-events">
    Reagiere auf das, was passiert: der Warenkorb wurde geladen, ein Artikel hinzugefügt, der Drawer geöffnet, Checkout geklickt.
  </Card>

  <Card title="Actions" icon="wand-magic-sparkles" href="/de/aftersell/cart/sdk-actions">
    Lies und ändere den Warenkorb: öffne ihn, füge einen Artikel hinzu, aktualisiere eine Menge, lies den aktuellen Zustand.
  </Card>

  <Card title="Hooks" icon="plug" href="/de/aftersell/cart/sdk-hooks">
    Ändere, wie der Warenkorb selbst funktioniert: Zeilen ausblenden oder umbenennen, neu ordnen, zusätzliche Daten anhängen, Add-to-cart steuern.
  </Card>
</Columns>

<Note>
  Wenn eines deiner Scripts beim Add-to-cart nicht mehr feuert, beginne bei [Add-to-cart-Abfangen](/de/aftersell/cart/add-to-cart-interception). Dort wird erklärt, warum Aftersell das Hinzufügen übernimmt, und jede Möglichkeit, ein Formular auszunehmen.
</Note>

Plus drei kleinere Mitglieder:

| Mitglied     | Wofür es ist                                                                |
| ------------ | --------------------------------------------------------------------------- |
| `ready()`    | Ein Promise, das aufgelöst wird, sobald der Warenkorb erstmals geladen hat. |
| `context`    | Servergerenderter Käufer-Kontext, synchron lesbar.                          |
| `shadowRoot` | Der Shadow Root des Warenkorbs, um Elemente im Drawer abzufragen.           |

<div id="events-actions-or-hooks">
  ## Events, Actions oder Hooks?
</div>

Die drei sind leicht zu verwechseln, und die falsche Wahl ist der häufigste Grund, warum ein Script nicht das tut, was sein Autor erwartet hat:

| Du willst…                                            | Verwende   | Beispiel                                                         |
| ----------------------------------------------------- | ---------- | ---------------------------------------------------------------- |
| Code ausführen, *wenn etwas passiert*                 | **Event**  | Ein Analytics-Event senden, wenn ein Artikel hinzugefügt wird.   |
| *Ändern, was im* Warenkorb *ist*                      | **Action** | Ein Gratisgeschenk hinzufügen, sobald die Summe \$50 übersteigt. |
| Ändern, *wie der Warenkorb funktioniert oder rendert* | **Hook**   | Gratisgeschenk-Zeilen im Drawer ausblenden.                      |

Die wichtigste Unterscheidung: Eine **Action ändert den tatsächlichen Warenkorb des Käufers** (und seine Gesamtsumme), während ein **Hook nur ändert, was gerendert wird**. Eine Zeile mit einem Hook auszublenden lässt sie im Warenkorb und in der Gesamtsumme; sie mit einer Action zu entfernen nimmt sie wirklich heraus.

<div id="how-and-when-it-loads">
  ## Wie und wann es lädt
</div>

Der Warenkorb lädt in zwei Phasen, und das SDK ist so gebaut, dass du nicht über die Reihenfolge nachdenken musst:

1. Ein kleiner **Stub** erstellt `window.aftersell.cart` sofort, sodass es immer da ist.
2. Das vollständige SDK lädt kurz danach und übernimmt, indem es den Stub an Ort und Stelle aufwertet — eine früher erfasste Referenz funktioniert also weiter.

Das ergibt zwei Kategorien von Aufrufen:

<Columns cols={2}>
  <Card title="Setup-Aufrufe: sofort sicher" icon="circle-check">
    `configure(...)`, `events.on(...)` und jeder `hooks.register*`-Aufruf. Werden vor dem Boot gepuffert und in Reihenfolge abgespielt, sobald das SDK lädt. Setze sie an den Anfang deines Scripts.
  </Card>

  <Card title="Actions: auf ready() warten" icon="clock">
    Alles unter `actions.*`. Führe sie innerhalb von `ready()` oder einem Event-Handler aus. Zu früh aufgerufen warnen sie in der Konsole und tun nichts — sicher: Die asynchronen lösen trotzdem auf, sodass eine `.then()`-Kette nicht bricht.
  </Card>
</Columns>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Set-up: fine at the top level, before the cart has loaded.
window.aftersell.cart.configure({ open_on_add_to_cart: 'always' });

window.aftersell.cart.events.on('item_added', (payload) => {
  console.log('Added', payload.item.title);
});

// Actions: wait until the cart is ready.
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  console.log(state.itemCount, 'items');
});
```

<div id="ready">
  ### ready()
</div>

`ready()` gibt ein Promise zurück, das aufgelöst wird, sobald das erste Laden des Warenkorbs **abgeschlossen** ist. Es wird sowohl bei Fehlschlag als auch bei Erfolg aufgelöst, sodass ein Käufer mit wackliger Verbindung dein Script nie hängen lässt. Prüfe `getCart()` auf `null`, statt anzunehmen, dass ein Warenkorb angekommen ist.

Ein Aufruf von `ready()`, nachdem der Warenkorb bereits geladen ist, wird sofort aufgelöst — es ist also sicher, es überall in deinem Code als allgemeines „der Warenkorb existiert jetzt“-Gate zu verwenden.

<Tip>
  Innerhalb eines Event-Handlers brauchst du `ready()` nicht. Wenn `cart_loaded`, `cart_updated` oder `item_added` ausgelöst wird, ist der Warenkorb geladen und Actions können sicher aufgerufen werden.
</Tip>

<div id="context">
  ## context
</div>

`window.aftersell.cart.context` enthält vom Server gerenderte Käuferdaten, synchron lesbar, ohne dass `ready()` nötig ist. Verwende es für Markt- oder Länder-Verzweigungen, die passieren müssen, bevor der Warenkorb lädt.

| Feld                      | Beschreibung                                                                    | Vor dem Boot verfügbar                                 |
| ------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------ |
| `shopify_market`          | Der Shopify-Markt des Käufers.                                                  | Ja                                                     |
| `customer_country`        | Zweibuchstabiger Ländercode.                                                    | Ja                                                     |
| `customer_currency`       | Aktiver Währungscode.                                                           | Ja                                                     |
| `money_format`            | Das Shopify-Geldformat des Shops.                                               | Ja                                                     |
| `backend_url`             | Direkter Backend-Host, als Fallback, wenn der App-Proxy nicht konfiguriert ist. | Ja                                                     |
| `storefront_access_token` | Token für Storefront-API-Aufrufe.                                               | **Nein** — wird hinzugefügt, wenn der Warenkorb bootet |

<Warning>
  `storefront_access_token` ist das eine `context`-Feld, das der Server nicht in `cart.context` rendert. Es wird `context` hinzugefügt, wenn der Warenkorb bootet — es am Anfang deines Scripts zu lesen ergibt also `undefined`. Warte zuerst auf `window.aftersell.cart.ready()`.
</Warning>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
if (window.aftersell.cart.context.customer_country === 'CA') {
  // Canada-only behavior, decided before the cart loads.
}
```

<Note>
  Um unterschiedliche Block-Einstellungen nach Markt, Land oder Währung anzuzeigen, verwende stattdessen [Bedingungen im Cart-Editor](/de/aftersell/cart/blocks-overview#show-or-hide-by-market-country-or-currency). Kein Script erforderlich. Die vollständige Conditions-UI gibt es heute bei [Rewards](/de/aftersell/cart/rewards-block#per-market-rewards).
</Note>

<div id="shadowroot">
  ## shadowRoot
</div>

Der Warenkorb wird innerhalb eines Shadow Root gerendert, sodass `document.querySelector` **nichts im Drawer sehen kann**. Um ein Element im Warenkorb zu erreichen, frage den Shadow Root ab:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const root = window.aftersell.cart.shadowRoot;
const button = root?.querySelector('.cart-external-checkout-button');
```

Ziele auf dieselben **öffentlichen `cart-external-*`-Klassen**, die auch [Custom CSS](/de/aftersell/cart/custom-css) verwendet. Das sind die unterstützten Griffe. Die `cart-internal-*`-Zwillinge sind die interne Verkabelung des Warenkorbs, frage also stattdessen die externen ab.

<Warning>
  Greif nur zum Shadow Root, wenn kein Block, keine Einstellung und kein Hook die Aufgabe erledigt. Ein Hook überlebt ein Cart-Redesign; eine DOM-Abfrage muss dein Code selbst pflegen.
</Warning>

Der Shadow Root ist erst da, wenn der Warenkorb gebootet hat — lies ihn also innerhalb von `ready()` oder einem Event-Handler statt am Anfang deines Scripts.

<div id="debugging">
  ## Debugging
</div>

Ein defektes Script darf nie Add-to-cart oder den Drawer lahmlegen, deshalb hält das SDK Fehler zurück, statt sie nach oben durchzureichen. Wo ein Fehler auftaucht, hängt davon ab, was kaputtging:

| Was fehlgeschlagen ist                                                              | Wo es erscheint                                      |
| ----------------------------------------------------------------------------------- | ---------------------------------------------------- |
| Dein Script warf auf oberster Ebene                                                 | `console.error`, mit der Zeile und dem, was nie lief |
| Ein [Event](/de/aftersell/cart/sdk-events)-Handler warf                             | `console.error`; die anderen Handler laufen weiter   |
| Ein [Hook](/de/aftersell/cart/sdk-hooks) warf                                       | Still. Landet im Debug-Kanal unten                   |
| Eine [Action](/de/aftersell/cart/sdk-actions) lief, bevor der Warenkorb geladen war | `console.warn`; der Aufruf tut nichts                |

<div id="when-your-script-throws">
  ### Wenn dein Script wirft
</div>

Ein benutzerdefiniertes Script **stoppt beim ersten Fehler**, sodass jedes `configure`, `events.on` und `hooks.register*` unterhalb dieser Zeile nie läuft. Der Warenkorb sagt das explizit:

```
[aftersell-cart] Initialization script error on line 12 — 4 more line(s) did not run;
any configure/events/hooks below are unregistered.
```

Das ist die Meldung, nach der du suchen solltest, wenn ein Handler, den du definitiv registriert hast, nie ausgelöst wird: Er wurde wahrscheinlich nie erreicht. Die Zeilennummer ist das Top-Level-Statement, an dem die Ausführung gestoppt hat, nicht die innere Funktion, die geworfen hat — und sie wird weggelassen statt geraten, wenn der Stack des Browsers nicht brauchbar ist.

Deine Scripts laufen außerdem unter ihren eigenen Dateinamen und erscheinen daher als `aftersell-cart-init.js` und `aftersell-cart-cart-update.js` in den DevTools. Du kannst sie im Sources-Panel öffnen und Breakpoints setzen wie in jeder anderen Datei.

<div id="the-debug-channel">
  ### Der Debug-Kanal
</div>

Hook-Fehler werden bewusst aus der Konsole ferngehalten, damit Käufer sie nie sehen. Sie landen stattdessen hier:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// After reproducing the problem, inspect what was swallowed:
window.aftersellCartDebugEvents.filter((entry) => entry.level === 'ERROR');

// Or watch them live:
window.addEventListener('aftersell-cart-debug', (event) => console.log(event.detail));
```

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

<Columns cols={2}>
  <Card title="Configure" icon="sliders" href="/de/aftersell/cart/sdk-configure">
    Jede Option, mit je einem Beispiel.
  </Card>

  <Card title="Events" icon="tower-broadcast" href="/de/aftersell/cart/sdk-events">
    Jedes Event, wann es ausgelöst wird und was du in einem Handler nicht tun solltest.
  </Card>

  <Card title="Actions" icon="wand-magic-sparkles" href="/de/aftersell/cart/sdk-actions">
    Jede Action, mit je einem Snippet.
  </Card>

  <Card title="Hooks" icon="plug" href="/de/aftersell/cart/sdk-hooks">
    Jeder Hook und wie sich Registrierungen kombinieren.
  </Card>

  <Card title="Cart-Objekt" icon="table-list" href="/de/aftersell/cart/sdk-cart-object">
    Die Struktur des Warenkorbs und seiner Zeilen.
  </Card>

  <Card title="Use Cases" icon="book-open" href="/de/aftersell/cart/sdk-use-cases">
    Vollständige, lauffähige Lösungen für häufige Anforderungen.
  </Card>
</Columns>
