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

# Afficher les données de metafields sur les lignes du panier

> Un cas d'usage du Cart SDK utilisant registerCartEnricher pour récupérer des metafields depuis l'API Storefront de Shopify sur chaque ligne du panier, puis les afficher.

Le panier connaît ce que l'API Ajax de Shopify lui indique : titres, prix, quantités, propriétés. Il ne connaît pas vos metafields. Un **enrichisseur de panier** (cart enricher) récupère des champs de produit ou de variante supplémentaires depuis l'API Storefront et les attache à chaque ligne correspondante, afin que vous puissiez afficher une estimation de livraison, un avertissement « expédié séparément », une liste d'ingrédients, ou toute autre information stockée sur le produit.

Utilisations typiques : fenêtres de livraison par produit, badges d'allergènes ou d'ingrédients, un indicateur « stock faible » personnalisé, des multiplicateurs de points de fidélité, des prix réservés aux abonnés.

<div id="register-the-enricher">
  ## Enregistrer l'enrichisseur
</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 }
  `,
});
```

Trois champs :

| Champ      | Description                                                                                                                                       |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`       | Espace de noms pour le résultat ; il atterrit dans `line.metadata[id]`. Doit être unique ; un second enregistrement avec le même `id` est ignoré. |
| `onType`   | `'Product'` ou `'ProductVariant'`. C'est aussi la clé de jointure, donc ID de produit vs ID de variante.                                          |
| `fragment` | Une sélection de champs GraphQL (sans accolades extérieures) insérée dans la requête Storefront. Les accolades doivent être équilibrées.          |

Chaque fois que le panier se charge ou change, Aftersell récupère votre fragment pour chaque produit ou variante du panier. La récupération est **non bloquante** : le panier s'affiche immédiatement et réémet `cart_updated` une fois les données arrivées. Un fragment lent ou en échec ne retarde ni ne casse jamais le panier.

<div id="read-the-data">
  ## Lire les données
</div>

Comme l'enrichissement est asynchrone, `line.metadata.delivery` vaut `undefined` jusqu'à ce que la première récupération aboutisse. Protégez toujours la lecture.

```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">
  ## L'afficher dans le panier
</div>

L'enrichissement place les données sur la ligne ; un [bloc de code personnalisé](/fr/aftersell/cart/custom-code-blocks) en mode React les dessine. Ajoutez le bloc comme **sous-bloc Cart items** afin qu'il s'affiche une fois par ligne et reçoive cette ligne via `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>
  Les valeurs enrichies reviennent de l'API Storefront **telles quelles et non assainies**. Affichez-les en tant que texte, comme ci-dessus, et jamais avec `dangerouslySetInnerHTML` ni en écrivant du HTML brut.
</Warning>

<div id="variant-level-data">
  ## Données au niveau de la variante
</div>

Définissez `onType: 'ProductVariant'` lorsque le metafield se trouve sur la variante plutôt que sur le produit :

```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">
  ## Plus que des metafields
</div>

Le fragment est inséré dans une requête de l'API Storefront, donc tout ce que l'API expose sur un `Product` ou un `ProductVariant` fonctionne, pas seulement les 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">
  ## Points à ne pas manquer
</div>

* **Protégez chaque lecture.** `metadata` vaut `{}` par défaut et votre espace de noms est `undefined` jusqu'à ce que la récupération aboutisse. Le panier s'affiche avant l'arrivée des données, toujours.
* **Chaque `id` est son propre espace de noms.** Plusieurs enrichisseurs coexistent sans collision, y compris ceux enregistrés par d'autres applications.
* **Les metafields doivent être visibles côté Storefront.** Un metafield qui n'est pas exposé à l'API Storefront renvoie `null`. Vérifiez la définition dans l'admin Shopify si vous ne recevez rien.
* **Gardez le fragment petit.** Il s'exécute pour chaque produit du panier, à chaque changement du panier. Demandez les champs que vous utilisez, pas tout.
* **Enregistrez au moment de la configuration.** C'est un hook, donc sa place est en haut de votre script d'initialisation.
* **Les accolades doivent être équilibrées.** Pas d'accolades extérieures autour du fragment, mais toute sélection imbriquée nécessite sa propre paire correspondante. Un fragment déséquilibré est rejeté.

<div id="where-to-go-next">
  ## Où aller ensuite
</div>

* **[`registerCartEnricher`](/fr/aftersell/cart/sdk-hooks#registercartenricher)** : la référence complète du hook.
* **[Blocs de code personnalisés](/fr/aftersell/cart/custom-code-blocks)** : afficher les données.
* **[Objet Cart](/fr/aftersell/cart/sdk-cart-object)** : où se trouve `metadata` sur une ligne.
