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

# Blocs Custom code

> Le bloc Custom code de l'Aftersell Cart : ajoutez votre propre HTML ou React n'importe où dans le tiroir, y compris à l'intérieur de Cart items.

> Le bloc **Custom code** ajoute votre propre HTML ou React au panier. Placez-le dans n'importe quelle section du tiroir, ou imbriquez-le dans [**Cart items**](/fr/aftersell/cart/cart-items-block) en tant que sous-bloc pour qu'il se répète à chaque ligne. Contrairement aux autres blocs, il n'a pas de paramètres Content ni de section Design : le bloc *est* le code, vous travaillez donc entièrement dans son onglet **Code**.

<Frame>
  <img src="https://mintcdn.com/aftersell/1Y3gBpUfxv16VGSW/images/aftersell/cart-custom-code-block-add-and-enable.gif?s=6717cc64a8765b0c06b65990f99e12ff" alt="Aperçu animé de l'ajout et de l'activation d'un bloc Custom code dans l'éditeur Aftersell Cart" title="Aperçu animé de l'ajout et de l'activation d'un bloc Custom code dans l'éditeur Aftersell Cart" width="1200" height="558" data-path="images/aftersell/cart-custom-code-block-add-and-enable.gif" />
</Frame>

<div id="add-and-turn-on-a-custom-code-block">
  ## Ajouter et activer un bloc Custom code
</div>

1. Ajoutez un bloc **Custom code** à n'importe quelle section, ou en tant que sous-bloc sous **Cart items**.
2. Sélectionnez-le et ouvrez l'onglet **Code**.
3. Choisissez **HTML** ou **React component**. Les nouveaux blocs sont en HTML par défaut.
4. Écrivez votre code.
5. Si vous avez choisi React, cliquez sur <span style={{display:'inline-flex',alignItems:'center',gap:'4px',background:'#1C1C1C',color:'#fff',border:'1px solid #0A0A0A',borderRadius:'4px',padding:'0 6px',fontSize:'0.85em',fontWeight:500,lineHeight:'1.4em',verticalAlign:'middle'}}><svg width="8" height="9" viewBox="0 0 10 12" fill="none" aria-hidden="true" style={{display:'block'}}><path d="M1.5 1.2v9.6L8.8 6 1.5 1.2Z" stroke="#fff" strokeWidth="1.5" strokeLinejoin="round" /></svg>Compile</span>.
6. Activez **"Use custom template"**. Pour ce bloc, cet interrupteur signifie « afficher mon code personnalisé », et il est désactivé par défaut, donc rien ne s'affiche tant que vous ne l'activez pas.
7. Gardez le bouton œil de la barre latérale activé pour que le bloc reste visible pour les acheteurs.

Le bouton œil et **"Use custom template"** doivent tous deux être activés pour que le bloc apparaisse.

<div id="behavior">
  ## Comportement
</div>

* Le bloc n'affiche rien tant que le panier n'est pas chargé.
* Il n'affiche rien non plus lorsque l'œil de la barre latérale est désactivé, que **"Use custom template"** est désactivé, que le code est vide, ou que React échoue à compiler ou à s'afficher. Comme un échec est silencieux, vérifiez votre bloc en [aperçu](/fr/aftersell/cart/previewing-carts) avant de publier.

<div id="html-mode">
  ## Mode HTML
</div>

Le mode HTML substitue un petit ensemble de jetons dans votre balisage. Il est destiné au contenu statique ou piloté par jetons, pas à l'exécution de logique.

* **Les balises `<script>` en ligne ne s'exécutent pas**, et le mode HTML n'a **aucun accès au SDK ni à `window`.**
* Pour la logique, utilisez le [**mode React**](#react-mode) ou les [Custom scripts](/fr/aftersell/cart/custom-scripts) avec le [Cart SDK](/fr/aftersell/cart/sdk-overview).

<div id="tokens">
  ### Jetons
</div>

Les valeurs des jetons sont des **chaînes formatées** (format monétaire de la boutique, un pourcentage avec `%`, ou une quantité), prêtes à être insérées dans le balisage :

| Jeton                    | Ce qu'il affiche                                                      |
| ------------------------ | --------------------------------------------------------------------- |
| `{{pre_cart_total}}`     | Total du panier avant remises.                                        |
| `{{post_cart_total}}`    | Total du panier après remises.                                        |
| `{{savings_amount}}`     | Montant économisé (total avant remise moins total après remise).      |
| `{{savings_percentage}}` | Économies en pourcentage, y compris le signe `%` (par exemple `15%`). |
| `{{cart_quantity}}`      | Nombre d'articles visibles dans le panier.                            |

<div id="example">
  ### Exemple
</div>

```html theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
<div class="cart-external-custom-code_html">
  You saved {{savings_amount}} ({{savings_percentage}})
</div>
```

<div id="react-mode">
  ## Mode React
</div>

Le mode React compile un composant et lui transmet les données du panier ainsi qu'une action `add-to-cart`.

* L'éditeur verrouille l'enveloppe sur `function CustomCode(props: CustomCodeProps) { … }`, et vous ne modifiez que le corps entre ces lignes.
* Vous devez cliquer sur <span style={{display:'inline-flex',alignItems:'center',gap:'4px',background:'#1C1C1C',color:'#fff',border:'1px solid #0A0A0A',borderRadius:'4px',padding:'0 6px',fontSize:'0.85em',fontWeight:500,lineHeight:'1.4em',verticalAlign:'middle'}}><svg width="8" height="9" viewBox="0 0 10 12" fill="none" aria-hidden="true" style={{display:'block'}}><path d="M1.5 1.2v9.6L8.8 6 1.5 1.2Z" stroke="#fff" strokeWidth="1.5" strokeLinejoin="round" /></svg>Compile</span> puis activer **"Use custom template"**, avant que le bloc ne s'affiche.
* Votre composant peut utiliser `useState`, `useEffect`, `useMemo`, `useRef` et `useCallback`.
* Contrairement au mode HTML, React s'exécute dans le contexte de la page, il peut donc appeler `window` et le [Cart SDK](/fr/aftersell/cart/sdk-overview) lorsqu'ils sont disponibles.
* Si votre composant génère des erreurs à l'exécution, le bloc n'affiche rien et le reste du panier continue de fonctionner.

<div id="props">
  ### Props
</div>

Les totaux et les montants d'économies sont des entiers dans l'[unité mineure](/fr/aftersell/cart/sdk-actions#formatmoneycents) de la devise (centimes pour l'USD), donc `$12.50` est `1250`, pas `12.50`. Ce ne sont pas des chaînes monétaires formatées comme les jetons HTML.

| Prop                                            | Type                        | Description                                                                                                                                           |
| ----------------------------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cart`                                          | `AftersellCart`             | Le panier actuel. Voir la [référence de l'objet cart](/fr/aftersell/cart/sdk-cart-object).                                                            |
| `line`                                          | `AftersellCartLine \| null` | Définie uniquement lorsque le bloc est un sous-bloc de Cart items (un rendu par ligne) ; `null` dans une section.                                     |
| `preCartTotal`                                  | `number`                    | Le total du panier **avant remises** (`original_total_price` de Shopify), dans l'unité mineure de la devise (par ex. centimes).                       |
| `postCartTotal`                                 | `number`                    | Le total du panier **après remises**, dans l'unité mineure de la devise.                                                                              |
| `savings`                                       | `{ amount, percentage }`    | Montant et pourcentage des économies.                                                                                                                 |
| `addProduct(variantId, quantity?, properties?)` | `function`                  | Ajoute un produit au panier, estampillé avec l'attribution de ce bloc afin que les [analyses](/fr/aftersell/cart/analytics) puissent le lui créditer. |

<div id="the-cart-and-line-shapes">
  ### Les structures cart et line
</div>

`cart` et `line` sont les mêmes objets que le SDK expose partout ailleurs, ils sont donc documentés une seule fois dans la **[référence de l'objet cart](/fr/aftersell/cart/sdk-cart-object)** : chaque champ du panier, d'une ligne et d'un bundle.

Ceux que vous utiliserez le plus : `cart.items`, `cart.itemCount`, `cart.totalPrice`, `line.title`, `line.quantity`, `line.finalLinePrice`.

Trois particularités propres à ce bloc :

* **`line` n'est définie que sur un sous-bloc de Cart items**, où votre composant s'affiche une fois par ligne. Placé en tant que section, `line` est `null` et vous lisez `cart.items` à la place.
* **Les composants de bundle ne figurent pas dans `cart.items`.** Lorsque des lignes sont [regroupées en bundle](/fr/aftersell/cart/sdk-use-case-bundles), seule la ligne d'ancrage apparaît ; ses composants se trouvent dans `line.bundle.children`.
* **Les lignes masquées par une [transformation de ligne](/fr/aftersell/cart/sdk-hooks#registerlinetransform) n'y figurent pas non plus**, bien qu'elles comptent toujours dans `cart.totalPrice`.

<div id="examples">
  ### Exemples
</div>

Afficher le nombre d'articles :

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  return (
    <div className="cart-external-custom-code_jsx">
      {props.cart.itemCount} items
    </div>
  );
}
```

En tant que sous-bloc de Cart items, utilisez `props.line` pour du contenu par produit. Le bloc s'affiche une fois par ligne, marqué avec le produit et la variante de cette ligne :

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  if (!props.line) return null;
  return (
    <div className="cart-external-custom-code_jsx">
      {props.line.productTitle}
      {props.line.variantTitle ? ` · ${props.line.variantTitle}` : ''}
    </div>
  );
}
```

<div id="reading-enrichment-metadata">
  ### Lire les métadonnées d'enrichissement
</div>

Chaque article de `cart.items` porte un champ `metadata` : un objet vide `{}` jusqu'à ce qu'un [enrichisseur de panier](/fr/aftersell/cart/sdk-hooks#registercartenricher) le remplisse. Une fois rempli, il est indexé par l'`id` de l'enrichisseur et contient les données Storefront du produit ou de la variante de cette ligne :

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  return (
    <ul>
      {(props.cart.items ?? []).map((item) => {
        const note = item.metadata?.shipping?.shippingNote;
        return (
          <li key={item.key}>
            {item.title}
            {note ? ` · ${note.value}` : ''}
          </li>
        );
      })}
    </ul>
  );
}
```

`metadata` est toujours présent et vaut par défaut un objet vide `{}` jusqu'à ce que la récupération asynchrone de l'enrichisseur se termine (le test « pas encore enrichi » est `Object.keys(item.metadata).length === 0`). Utilisez le chaînage optionnel (`item.metadata?.enricherId`) lorsque vous lisez la clé d'un enrichisseur spécifique, car cette clé est absente tant que l'enrichissement n'a pas abouti.

<div id="reading-discount-codes-and-line-discounts">
  ### Lire les codes de réduction et les remises de ligne
</div>

`cart.discountCodes` liste les codes de réduction appliqués au panier, et le champ `discountAllocations` de chaque ligne liste les remises appliquées à cette ligne spécifique :

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomCode(props) {
  const codes = props.cart.discountCodes;
  return (
    <div>
      {codes.length > 0 && (
        <p>Active discounts: {codes.join(', ')}</p>
      )}
      <ul>
        {(props.cart.items ?? []).map((item) => {
          return (
            <li key={item.key}>
              {item.title}
              {item.discountAllocations.map(
                (discount) => ` · ${discount.title} (-${(discount.amount / 100).toFixed(2)})`
              )}
            </li>
          );
        })}
      </ul>
    </div>
  );
}
```

<div id="placement-and-limits">
  ## Placement et limites
</div>

* **Région :** n'importe laquelle (haut, corps ou bas). Également disponible en tant que sous-bloc de Cart items.
* **Maximum :** illimité.
* **État :** panier rempli et vide (en tant que bloc de section). En tant que sous-bloc de Cart items, il ne s'affiche que lorsque le panier contient des lignes, une instance par ligne.
* Non verrouillé, vous pouvez donc le supprimer ou le masquer.
* Il n'y a pas de section Design par bloc. Stylisez via votre propre balisage, le [**CSS personnalisé**](/fr/aftersell/cart/custom-css) et vos [**paramètres de design**](/fr/aftersell/cart/design-settings) globaux.

<div id="when-to-use-custom-code-block-vs-custom-template-vs-custom-script">
  ## Quand utiliser un bloc custom code vs un modèle personnalisé vs un script personnalisé
</div>

|                                                                | Ce qu'il fait                                                                              | Quand l'utiliser                                                                             | Exemple                                                                                                                                                                                               |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Bloc Custom code**                                           | Ajoute un *nouveau* bloc composé de votre propre HTML ou React.                            | Quelque chose que les blocs intégrés ne couvrent pas.                                        | Une ligne de total estimé qui ajoute vos frais d'expédition forfaitaires au total du panier, ou un compte à rebours de date limite de livraison au-dessus du bouton de paiement.                      |
| **[Modèle personnalisé](/fr/aftersell/cart/custom-templates)** | Remplace le rendu d'un bloc *existant* par votre JSX, en utilisant les données de ce bloc. | Le bloc intégré est presque bon, mais vous avez besoin d'un balisage différent.              | Reconstruire la [ligne Product](/fr/aftersell/cart/cart-items-block#custom-template) pour que le nom de la variante, les économies et le sélecteur de quantité tiennent sur une seule ligne.          |
| **[Script personnalisé](/fr/aftersell/cart/custom-scripts)**   | Exécute du JavaScript sur le panier via le [Cart SDK](/fr/aftersell/cart/sdk-overview).    | Logique, événements et configuration à l'échelle du panier plutôt que du balisage du tiroir. | Dépensez \$75, obtenez un tote bag gratuit : [ajoutez le cadeau](/fr/aftersell/cart/sdk-use-case-free-gift) une fois que le panier franchit le seuil, et retirez-le si l'acheteur repasse en dessous. |
