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

# Vis metafield-data på kurvlinjer

> En Cart SDK-use case, der bruger registerCartEnricher til at hente metafields fra Shopify Storefront API til hver kurvlinje og derefter rendere dem.

Kurven ved, hvad Shopifys Ajax API fortæller den: titler, priser, antal, properties. Den kender ikke dine metafields. En **cart enricher** henter ekstra produkt- eller variantfelter fra Storefront API'et og vedhæfter dem til hver matchende linje, så du kan vise et leveringsestimat, en "sendes separat"-advarsel, en ingrediensliste eller alt andet, du gemmer på produktet.

Typiske anvendelser: leveringsvinduer pr. produkt, allergen- eller ingrediensbadges, et custom "lav lagerbeholdning"-flag, multiplikatorer for loyalitetspoint, priser kun for abonnenter.

<div id="register-the-enricher">
  ## Registrér enricheren
</div>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerCartEnricher({
  id: 'delivery',
  onType: 'Product',
  fragment: `
    deliveryWindow: metafield(namespace: "custom", key: "delivery_window") { value }
    shipsSeparately: metafield(namespace: "custom", key: "ships_separately") { value }
  `,
});
```

Tre felter:

| Felt       | Beskrivelse                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `id`       | Namespace for resultatet; det lander på `line.metadata[id]`. Skal være unikt; en anden registrering med samme `id` ignoreres. |
| `onType`   | `'Product'` eller `'ProductVariant'`. Også join-nøglen, altså produkt-ID vs. variant-ID.                                      |
| `fragment` | En GraphQL-feltudvælgelse (uden ydre klammer), der splejses ind i Storefront-forespørgslen. Klammer skal balancere.           |

Hver gang kurven indlæses eller ændres, henter Aftersell dit fragment for hvert produkt eller variant i kurven. Hentningen er **ikke-blokerende**: kurven renderes med det samme og gen-udsender `cart_updated`, når dataene lander. Et langsomt eller fejlende fragment forsinker eller ødelægger aldrig kurven.

<div id="read-the-data">
  ## Læs dataene
</div>

Fordi berigelse er asynkron, er `line.metadata.delivery` `undefined`, indtil den første hentning resolves. Beskyt altid læsningen.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('cart_updated', (state) => {
  state.items.forEach((line) => {
    const deliveryWindow = line.metadata.delivery?.deliveryWindow?.value;
    if (!deliveryWindow) return; // not fetched yet

    console.log(line.title, 'arrives in', deliveryWindow);
  });
});
```

<div id="render-it-in-the-cart">
  ## Render det i kurven
</div>

Berigelse lægger dataene på linjen; en [Custom code-blok](/da/aftersell/cart/custom-code-blocks) i React-tilstand tegner det. Tilføj blokken som en **Cart items-underblok**, så den renderes én gang pr. linje og modtager den linje som `props.line`:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  const data = props.line?.metadata?.delivery;
  const window_ = data?.deliveryWindow?.value;

  if (!window_) return null;

  return (
    <div className="cart-external-custom-code_html" style={{ fontSize: '12px', opacity: 0.7 }}>
      Arrives in {window_}
    </div>
  );
}
```

<Warning>
  Berigede værdier kommer tilbage fra Storefront API'et **som de er og usaniterede**. Render dem som tekst, som ovenfor, og aldrig med `dangerouslySetInnerHTML` eller ved at skrive rå HTML.
</Warning>

<div id="variant-level-data">
  ## Data på variantniveau
</div>

Sæt `onType: 'ProductVariant'`, når metafieldet ligger på varianten frem for produktet:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerCartEnricher({
  id: 'pricing',
  onType: 'ProductVariant',
  fragment: `
    anchorPrice: metafield(namespace: "custom", key: "anchor_price") { value }
    subscriberPrice: metafield(namespace: "custom", key: "subscriber_price") { value }
  `,
});
```

<div id="more-than-metafields">
  ## Mere end metafields
</div>

Fragmentet splejses ind i en Storefront API-forespørgsel, så alt, API'et eksponerer på et `Product` eller `ProductVariant`, virker, ikke kun metafields:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerCartEnricher({
  id: 'productInfo',
  onType: 'Product',
  fragment: `
    tags
    vendor
    productType
    availableForSale
  `,
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Then: warn about anything from a drop-ship vendor.
window.aftersell.cart.events.on('cart_updated', (state) => {
  const hasDropship = state.items.some((line) => {
    const tags = line.metadata.productInfo?.tags;
    return tags?.includes('dropship');
  });
});
```

<div id="things-to-get-right">
  ## Ting du skal have styr på
</div>

* **Beskyt hver læsning.** `metadata` er som standard `{}`, og dit namespace er `undefined`, indtil hentningen resolves. Kurven renderes, før dataene ankommer, altid.
* **Hvert `id` er sit eget namespace.** Flere enrichers sameksisterer uden at kollidere, inklusive dem registreret af andre apps.
* **Metafields skal være Storefront-synlige.** Et metafield, der ikke er eksponeret for Storefront API'et, returnerer `null`. Tjek definitionen i Shopify admin, hvis du intet får tilbage.
* **Hold fragmentet lille.** Det kører for hvert produkt i kurven, ved hver kurvændring. Bed om de felter, du bruger, ikke alt.
* **Registrér på opsætningstidspunktet.** Det er en hook, så den hører hjemme øverst i dit Initialization-script.
* **Klammer skal balancere.** Ingen ydre klammer omkring fragmentet, men enhver indlejret udvælgelse skal have sit eget matchende par. Et ubalanceret fragment afvises.

<div id="where-to-go-next">
  ## Hvor du kan gå hen herfra
</div>

* **[`registerCartEnricher`](/da/aftersell/cart/sdk-hooks#registercartenricher)**: den fulde hook-reference.
* **[Custom code-blokke](/da/aftersell/cart/custom-code-blocks)**: rendering af dataene.
* **[Cart-objektet](/da/aftersell/cart/sdk-cart-object)**: hvor `metadata` sidder på en linje.
