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

# Oversigt

> Sådan fungerer Aftersell Cart SDK: det globale indgangspunkt, API'ets fire dele, hvornår det indlæses, og hvordan du kører kode mod det sikkert.

**Cart SDK** er et JavaScript-API til Aftersell Cart på din storefront. Det lader dig ændre, hvordan kurven opfører sig, reagere på hvad kunderne gør, og læse eller ændre kurvens indhold fra kode.

Du kører SDK-kode gennem [Custom scripts](/da/aftersell/cart/custom-scripts) eller gennem en [Custom code-bloks](/da/aftersell/cart/custom-code-blocks) React-tilstand for en blok, der renderer sin egen UI.

<Note>
  Meget af det, forhandlere beder SDK'et om, findes allerede som en indstilling. Før du skriver et script, så tjek om en [kurv-blok](/da/aftersell/cart/blocks-overview), [betingelser efter marked/land/valuta](/da/aftersell/cart/blocks-overview#show-or-hide-by-market-country-or-currency) eller en [kurvindstilling](/da/aftersell/cart/cart-settings) allerede gør det. De bliver ved med at virke gennem redesigns af kurven, og det gør dit script måske ikke.
</Note>

<div id="the-global-entry-point">
  ## Det globale indgangspunkt
</div>

Alt hænger på én global:

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

<Note>
  **Hvert snippet i disse docs skriver `window.aftersell.cart` fuldt ud**, så hvert enkelt af dem virker alene, når du indsætter det. Det er også helt gyldigt at aliasere det én gang (`const cart = window.aftersell.cart;`) og bruge `cart` derefter, og det er sikkert selv før kurven er indlæst. Husk bare at inkludere den linje, hvis du forkorter et snippet, da et nøgent `cart` alene kaster `cart is not defined`.
</Note>

Fire dele gør arbejdet:

<Columns cols={2}>
  <Card title="Configure" icon="sliders" href="/da/aftersell/cart/sdk-configure">
    Indstil hvordan kurven opfører sig: hvornår skuffen åbner, hvordan beløb formateres, om Aftersell opsnapper add-to-cart.
  </Card>

  <Card title="Events" icon="tower-broadcast" href="/da/aftersell/cart/sdk-events">
    Reagér på hvad der sker: kurven blev indlæst, en vare blev tilføjet, skuffen åbnede, der blev klikket på checkout.
  </Card>

  <Card title="Actions" icon="wand-magic-sparkles" href="/da/aftersell/cart/sdk-actions">
    Læs og ændr kurven: åbn den, tilføj en vare, opdater et antal, læs den aktuelle tilstand.
  </Card>

  <Card title="Hooks" icon="plug" href="/da/aftersell/cart/sdk-hooks">
    Ændr hvordan kurven selv fungerer: skjul eller omdøb linjer, omarranger dem, vedhæft ekstra data, styr add-to-cart.
  </Card>
</Columns>

<Note>
  Hvis et script hos dig holdt op med at fyre ved add to cart, så start med [Add to cart-interception](/da/aftersell/cart/add-to-cart-interception). Den forklarer, hvorfor Aftersell overtager tilføjelsen, og hver måde at fritage en formular på.
</Note>

Plus tre mindre medlemmer:

| Medlem       | Hvad det bruges til                                              |
| ------------ | ---------------------------------------------------------------- |
| `ready()`    | Et Promise, der resolves, når kurven er indlæst første gang.     |
| `context`    | Server-renderet køberkontekst, som kan læses synkront.           |
| `shadowRoot` | Kurvens shadow root, til at forespørge elementer inde i skuffen. |

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

De tre er nemme at blande sammen, og at vælge den forkerte er den mest almindelige grund til, at et script ikke gør det, forfatteren forventede:

| Du vil…                                        | Brug       | Eksempel                                          |
| ---------------------------------------------- | ---------- | ------------------------------------------------- |
| Køre kode *når noget sker*                     | **Event**  | Send et analytics-event, når en vare tilføjes.    |
| *Ændre hvad der er i* kurven                   | **Action** | Tilføj en gratis gave, når totalen passerer \$50. |
| Ændre *hvordan kurven fungerer eller renderer* | **Hook**   | Skjul linjer med gratis gaver fra skuffen.        |

Den skelnen, der betyder mest: en **action ændrer kundens faktiske kurv** (og deres total), mens en **hook kun ændrer hvad der renderes**. Skjuler du en linje med en hook, forbliver den i kurven og i totalen; fjerner du den med en action, ryger den ud for alvor.

<div id="how-and-when-it-loads">
  ## Hvordan og hvornår det indlæses
</div>

Kurven indlæses i to trin, og SDK'et er bygget, så du ikke behøver tænke på rækkefølgen:

1. En lille **stub** opretter `window.aftersell.cart` med det samme, så det altid er der.
2. Det fulde SDK indlæses kort efter og tager over ved at opgradere stubben på stedet, så en reference, du fangede tidligere, bliver ved med at virke.

Det giver dig to kategorier af kald:

<Columns cols={2}>
  <Card title="Opsætningskald: sikre med det samme" icon="circle-check">
    `configure(...)`, `events.on(...)` og hvert `hooks.register*`-kald. Buffres før boot og afspilles i rækkefølge, når SDK'et indlæses. Placér dem øverst i dit script.
  </Card>

  <Card title="Actions: vent på ready()" icon="clock">
    Alt under `actions.*`. Kør dem inde i `ready()` eller en event-handler. Kaldes de for tidligt, advarer de i konsollen og gør ingenting, sikkert: de asynkrone resolves stadig, så en `.then()`-kæde bryder ikke.
  </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()` returnerer et Promise, der resolves, når den første kurvindlæsning **er afgjort**. Det resolves både ved fejl og succes, så en kunde på en ustabil forbindelse aldrig efterlader dit script hængende. Tjek `getCart()` for `null` i stedet for at antage, at en kurv kom frem.

Kaldes `ready()`, efter kurven allerede er indlæst, resolves det med det samme, så det er sikkert at bruge som en generel "kurven findes nu"-port hvor som helst i din kode.

<Tip>
  Du behøver ikke `ready()` inde i en event-handler. Når `cart_loaded`, `cart_updated` eller `item_added` fyrer, er kurven indlæst, og actions er sikre at kalde.
</Tip>

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

`window.aftersell.cart.context` indeholder køberdata renderet af serveren, som kan læses synkront, uden brug af `ready()`. Brug det til marked- eller landeforgrening, der skal ske, før kurven indlæses.

| Felt                      | Beskrivelse                                                                     | Tilgængeligt før boot                 |
| ------------------------- | ------------------------------------------------------------------------------- | ------------------------------------- |
| `shopify_market`          | Køberens Shopify-marked.                                                        | Ja                                    |
| `customer_country`        | Landekode på to bogstaver.                                                      | Ja                                    |
| `customer_currency`       | Aktiv valutakode.                                                               | Ja                                    |
| `money_format`            | Butikkens Shopify-beløbsformat.                                                 | Ja                                    |
| `backend_url`             | Direkte backend-host, brugt som fallback, når app-proxyen ikke er konfigureret. | Ja                                    |
| `storefront_access_token` | Token til Storefront API-kald.                                                  | **Nej** — tilføjes, når kurven booter |

<Warning>
  `storefront_access_token` er det ene `context`-felt, serveren ikke renderer ind i `cart.context`. Det tilføjes til `context`, når kurven booter, så læser du det øverst i dit script, får du `undefined`. Await `window.aftersell.cart.ready()` først.
</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>
  For at vise forskellige blokindstillinger efter marked, land eller valuta skal du bruge [betingelser i cart editoren](/da/aftersell/cart/blocks-overview#show-or-hide-by-market-country-or-currency) i stedet. Intet script kræves. Den fulde Conditions-UI findes på [Rewards](/da/aftersell/cart/rewards-block#per-market-rewards) i dag.
</Note>

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

Kurven renderer inde i en shadow root, så `document.querySelector` **kan ikke se noget inde i skuffen**. For at nå et element i kurven skal du forespørge shadow root'en:

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

Målret de samme **offentlige `cart-external-*`-klasser**, som [Custom CSS](/da/aftersell/cart/custom-css) bruger. Det er de understøttede håndtag. `cart-internal-*`-tvillingerne er kurvens eget maskinrum, så forespørg de eksterne i stedet.

<Warning>
  Ræk kun ud efter shadow root'en, når ingen blok, indstilling eller hook klarer opgaven. En hook overlever et redesign af kurven; en DOM-forespørgsel er din kodes eget vedligeholdelsesproblem.
</Warning>

Shadow root'en er der først, når kurven er bootet, så læs den inde i `ready()` eller en event-handler i stedet for øverst i dit script.

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

Et defekt script må aldrig tage add-to-cart eller skuffen ned, så SDK'et indkapsler fejl i stedet for at lade dem boble op. Hvor en fejl viser sig, afhænger af, hvad der gik i stykker:

| Hvad fejlede                                                              | Hvor det viser sig                                                |
| ------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| Dit script kastede på øverste niveau                                      | `console.error`, med angivelse af linjen og hvad der aldrig kørte |
| En [event](/da/aftersell/cart/sdk-events)-handler kastede                 | `console.error`; de andre handlers kører stadig                   |
| En [hook](/da/aftersell/cart/sdk-hooks) kastede                           | Stille. Ryger i debug-kanalen nedenfor                            |
| En [action](/da/aftersell/cart/sdk-actions) kørte, før kurven var indlæst | `console.warn`; kaldet gør ingenting                              |

<div id="when-your-script-throws">
  ### Når dit script kaster
</div>

Et custom script **stopper ved den første fejl**, så hvert `configure`, `events.on` og `hooks.register*` under den linje kører aldrig. Kurven siger det eksplicit:

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

Det er beskeden, du skal kigge efter, når en handler, du helt sikkert registrerede, aldrig fyrer: den blev sandsynligvis aldrig nået. Linjenummeret er top-niveau-statementet, hvor eksekveringen stoppede, ikke den indre funktion, der kastede, og det udelades i stedet for at blive gættet, hvis browserens stack ikke er brugbar.

Dine scripts kører også under deres egne filnavne, så de vises som `aftersell-cart-init.js` og `aftersell-cart-cart-update.js` i DevTools. Du kan åbne dem fra Sources-panelet og sætte breakpoints som i enhver anden fil.

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

Hook-fejl holdes bevidst væk fra konsollen, så kunder aldrig ser dem. De ryger i stedet her:

```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">
  ## Hvor du kan gå hen herfra
</div>

<Columns cols={2}>
  <Card title="Configure" icon="sliders" href="/da/aftersell/cart/sdk-configure">
    Hver mulighed, med et eksempel til hver.
  </Card>

  <Card title="Events" icon="tower-broadcast" href="/da/aftersell/cart/sdk-events">
    Hvert event, hvornår det fyrer, og hvad du ikke skal gøre i en handler.
  </Card>

  <Card title="Actions" icon="wand-magic-sparkles" href="/da/aftersell/cart/sdk-actions">
    Hver action, med et snippet til hver.
  </Card>

  <Card title="Hooks" icon="plug" href="/da/aftersell/cart/sdk-hooks">
    Hver hook, og hvordan registreringer sammensættes.
  </Card>

  <Card title="Cart-objektet" icon="table-list" href="/da/aftersell/cart/sdk-cart-object">
    Kurvens og dens linjers form.
  </Card>

  <Card title="Use cases" icon="book-open" href="/da/aftersell/cart/sdk-use-cases">
    Komplette, kørbare løsninger på almindelige ønsker.
  </Card>
</Columns>
