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

# Scripts personnalisés

> Exécutez du JavaScript personnalisé dans le panier Aftersell avec les emplacements de script Initialization et On cart update.

Les scripts personnalisés vous permettent d'exécuter votre propre JavaScript sur le panier à l'aide du [Cart SDK](/fr/aftersell/cart/sdk-overview). Ajoutez-les dans l'éditeur de panier sous **Cart settings → Custom script**, où un menu déroulant permet de basculer entre deux emplacements : **Initialization** et **On cart update**.

Écrivez du JavaScript pur dans ces éditeurs, sans balises `<script>`. **On cart update** dispose d'une action **Reset to default** qui restaure son modèle de départ ; **Initialization** n'en a pas, gardez donc votre propre copie avant de l'effacer.

<Note>
  Une grande partie de ce que les marchands avaient l'habitude de scripter est désormais un paramètre intégré. Consultez d'abord [Avant d'écrire un script](/fr/aftersell/cart/sdk-use-cases#before-you-write-a-script) : un paramètre continue de fonctionner à travers les refontes du panier, ce qui n'est pas forcément le cas de votre script.
</Note>

<div id="which-slot-to-use">
  ## Quel emplacement utiliser
</div>

|                     | Initialization                                                                                                                                                                                 | On cart update                                                                  |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **S'exécute**       | Une fois, au chargement du panier.                                                                                                                                                             | À chaque modification du panier après le premier chargement.                    |
| **Vous écrivez**    | Le script entier.                                                                                                                                                                              | Uniquement le corps du gestionnaire. Le wrapper `cart_updated` est verrouillé.  |
| **À utiliser pour** | Enregistrer un comportement une seule fois : [`configure`](/fr/aftersell/cart/sdk-configure), [`events.on`](/fr/aftersell/cart/sdk-events), [`hooks.register*`](/fr/aftersell/cart/sdk-hooks). | Les règles qui doivent être réévaluées en fonction du contenu actuel du panier. |
| **Exemple**         | Masquer les lignes de cadeau gratuit avec une transformation de ligne.                                                                                                                         | Maintenir un cadeau gratuit synchronisé avec un seuil de dépense.               |

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

Le script **Initialization** s'exécute **une fois au chargement du panier**. C'est votre point d'entrée pour tout mettre en place : configurer le comportement du panier, s'abonner aux événements et enregistrer des hooks. Le [SDK](/fr/aftersell/cart/sdk-overview) est disponible sous `window.aftersell.cart`.

Les appels de configuration que vous effectuez ici ([`configure(...)`](/fr/aftersell/cart/sdk-configure), [`events.on(...)`](/fr/aftersell/cart/sdk-events), [`hooks.*`](/fr/aftersell/cart/sdk-hooks)) peuvent être appelés en toute sécurité en haut du script, même avant que le panier ait complètement démarré ; ils sont mis en mémoire tampon et appliqués une fois le démarrage terminé. Les actions qui lisent ou modifient le panier (comme [`addItem`](/fr/aftersell/cart/sdk-actions#additemvariantid-quantity) ou [`getCart`](/fr/aftersell/cart/sdk-actions#getcart)) doivent s'exécuter à l'intérieur de [`ready()`](/fr/aftersell/cart/sdk-overview#ready) ou d'un gestionnaire d'événement.

L'emplacement démarre avec trois exemples **mis en commentaire** (ouvrir le tiroir à chaque ajout, réagir à `cart_loaded` et masquer les lignes de cadeau gratuit), donc un script Initialization intact ne fait rien. Décommentez-en un pour l'essayer, ou remplacez-les.

La forme naturelle pour cet emplacement est un **enregistrement unique sans aucun événement** : enregistrez le comportement une fois et laissez le panier l'appliquer à partir de ce moment. Masquer les lignes de cadeau gratuit du tiroir, sans modifier le total, est l'exemple fourni de ce schéma :

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

[`registerLineTransform`](/fr/aftersell/cart/sdk-hooks#registerlinetransform) s'exécute pour chaque ligne au moment de son rendu, et `setHidden` n'affecte que l'affichage : la ligne reste dans le panier et compte toujours dans le total, elle n'apparaît simplement pas dans le tiroir. Consultez [Masquer et renommer les lignes du panier](/fr/aftersell/cart/sdk-use-case-hide-lines) pour découvrir tout ce qu'une transformation peut faire.

Les actions qui lisent le panier vont à l'intérieur de `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');
});
```

Accéder au DOM du panier nécessite la même attente, ainsi que [`shadowRoot`](/fr/aftersell/cart/sdk-overview#shadowroot) : le panier est rendu à l'intérieur d'un shadow root, donc `document.querySelector` ne peut rien voir dans le tiroir.

<Tip>
  Vous souhaitez appliquer une logique conditionnelle selon le marché, le pays ou la devise **avant** le chargement du panier ? Lisez plutôt [`context`](/fr/aftersell/cart/sdk-overview#context). Il est disponible de manière synchrone, sans `ready()` nécessaire, ce qui vous permet d'ignorer complètement l'enregistrement des gestionnaires pour les acheteurs auxquels une règle ne s'applique pas.
</Tip>

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

Le script **On cart update** s'exécute à chaque modification du panier. Il s'agit d'un wrapper verrouillé autour d'un abonnement `cart_updated` : vous n'éditez que le corps, et votre code reçoit le `cart` mis à jour.

Cet emplacement est destiné aux règles qui doivent être **réévaluées à chaque modification du panier**. Un seuil de cadeau gratuit est le cas classique (dépensez \$75, recevez un tote bag gratuit), car la réponse dépend du contenu actuel et rien d'autre ne peut vous signaler quand il change :

```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">
  ### Maintenir le panier dans un état souhaité
</div>

La ligne `if (shouldHaveGift === hasGift) return;` est ce qui rend ce code sûr, et elle se généralise à tout script qui maintient le panier dans un état souhaité. Cet emplacement réagit aux modifications du panier tout en en provoquant, donc chaque `addItem` ou `removeItem` le fait se réexécuter. Décrivez l'état que vous voulez, comparez-le à l'état que vous avez, et sortez immédiatement lorsqu'ils concordent déjà, afin que le gestionnaire converge après un seul passage au lieu de boucler. Consultez [les deux règles](/fr/aftersell/cart/sdk-events#the-two-rules) pour voir la version sans garde-fou à éviter et comprendre pourquoi la charge utile est en lecture seule.

Sur une boutique plus lente, il vaut également la peine de conserver un indicateur d'exécution en cours au niveau du module, afin que deux modifications rapides ne puissent pas toutes deux déclencher un ajout avant que le premier n'aboutisse.

<Note>
  `cart_updated` ne se déclenche que sur les modifications **après** le premier chargement ([chronologie des événements](/fr/aftersell/cart/sdk-events#cart_updated)), donc un script dans cet emplacement ne réconciliera pas un panier qui remplit déjà les conditions au chargement de la page. Pour une version qui gère les deux cas, abonnez-vous à `cart_loaded` et `cart_updated` avec la même fonction depuis l'emplacement **Initialization**. Consultez [Ajouter automatiquement un cadeau gratuit à un seuil](/fr/aftersell/cart/sdk-use-case-free-gift).
</Note>

<div id="when-a-script-breaks">
  ## Quand un script échoue
</div>

Chaque emplacement s'exécute dans son propre bac à sable, donc un script **Initialization** défaillant ne peut pas empêcher **On cart update** de s'exécuter, et aucun des deux ne peut casser le panier lui-même.

En revanche, au sein d'un emplacement, l'exécution **s'arrête à la première erreur**. Tout ce qui se trouve en dessous de cette ligne est ignoré, ce qui signifie que tout `configure`, `events.on` ou `hooks.register*` plus bas n'est jamais enregistré. C'est l'explication habituelle du « mon gestionnaire ne se déclenche jamais » alors que le code semble correct.

Le panier indique la ligne défaillante dans la console du navigateur, et chaque emplacement s'exécute sous son propre nom de fichier (`aftersell-cart-init.js` et `aftersell-cart-cart-update.js`), vous pouvez donc ouvrir l'un ou l'autre depuis le panneau Sources des DevTools et poser des points d'arrêt. Consultez [Débogage](/fr/aftersell/cart/sdk-overview#debugging) pour les messages exacts, ainsi que pour le canal de débogage qui capture les échecs de hooks tenus à l'écart de la console.

Comme `cart_loaded` [est rejoué pour les abonnés tardifs](/fr/aftersell/cart/sdk-events#cart_loaded), l'ordre d'enregistrement n'a jamais d'importance. La structure la plus sûre consiste à tout enregistrer d'abord et à effectuer le travail risqué à l'intérieur des gestionnaires, où une exception est isolée à ce gestionnaire.

<div id="where-to-go-next">
  ## Pour aller plus loin
</div>

* **[Cart SDK](/fr/aftersell/cart/sdk-overview)** : les scripts personnalisés sont le moyen d'exécuter du code SDK. Consultez les références [configure](/fr/aftersell/cart/sdk-configure), [events](/fr/aftersell/cart/sdk-events), [actions](/fr/aftersell/cart/sdk-actions) et [hooks](/fr/aftersell/cart/sdk-hooks) pour la surface complète, l'[objet cart](/fr/aftersell/cart/sdk-cart-object) pour la forme de ce que reçoivent les gestionnaires, et les [cas d'usage](/fr/aftersell/cart/sdk-use-cases) pour des extraits prêts à l'emploi.
* **[Blocs de code personnalisé](/fr/aftersell/cart/custom-code-blocks)** : pour ajouter du balisage au panier. Notez que le mode HTML du bloc Custom code n'exécute **pas** de JavaScript ; utilisez les scripts personnalisés (ou le mode React du bloc) pour la logique.
