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

> Ejecuta JavaScript personalizado en el Aftersell Cart con los slots de script Initialization y On cart update.

Los scripts personalizados te permiten ejecutar tu propio JavaScript sobre el carrito usando el [Cart SDK](/es/aftersell/cart/sdk-overview). Agrégalos en el editor del carrito en **Cart settings → Custom script**, donde un menú desplegable alterna entre dos slots: **Initialization** y **On cart update**.

Escribe JavaScript puro en estos editores, sin etiquetas `<script>`. **On cart update** tiene una acción **Reset to default** que restaura su plantilla inicial; **Initialization** no, así que guarda tu propia copia antes de borrarlo.

<Note>
  Mucho de lo que los comerciantes solían resolver con scripts ahora es una configuración integrada. Consulta primero [Antes de escribir un script](/es/aftersell/cart/sdk-use-cases#before-you-write-a-script): una configuración sigue funcionando a través de rediseños del carrito, y tu script podría no hacerlo.
</Note>

<div id="which-slot-to-use">
  ## Qué slot usar
</div>

|                 | Initialization                                                                                                                                                                           | On cart update                                                           |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| **Se ejecuta**  | Una vez, cuando el carrito se carga.                                                                                                                                                     | En cada cambio del carrito después de la primera carga.                  |
| **Tú escribes** | Todo el script.                                                                                                                                                                          | Solo el cuerpo del handler. El envoltorio `cart_updated` está bloqueado. |
| **Úsalo para**  | Registrar comportamiento una sola vez: [`configure`](/es/aftersell/cart/sdk-configure), [`events.on`](/es/aftersell/cart/sdk-events), [`hooks.register*`](/es/aftersell/cart/sdk-hooks). | Reglas que deben reevaluarse contra el contenido actual del carrito.     |
| **Ejemplo**     | Ocultar líneas de regalo gratis con una transformación de línea.                                                                                                                         | Mantener un regalo gratis sincronizado con un umbral de gasto.           |

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

El script de **Initialization** se ejecuta **una vez cuando el carrito se carga**. Es tu punto de entrada para configurar todo: configurar el comportamiento del carrito, suscribirte a eventos y registrar hooks. El [SDK](/es/aftersell/cart/sdk-overview) está disponible como `window.aftersell.cart`.

Las llamadas de configuración que hagas aquí ([`configure(...)`](/es/aftersell/cart/sdk-configure), [`events.on(...)`](/es/aftersell/cart/sdk-events), [`hooks.*`](/es/aftersell/cart/sdk-hooks)) se pueden llamar con seguridad al inicio del script incluso antes de que el carrito haya arrancado por completo; se almacenan en búfer y se aplican una vez que lo hace. Las acciones que leen o cambian el carrito (como [`addItem`](/es/aftersell/cart/sdk-actions#additemvariantid-quantity) o [`getCart`](/es/aftersell/cart/sdk-actions#getcart)) deben ejecutarse dentro de [`ready()`](/es/aftersell/cart/sdk-overview#ready) o de un handler de eventos.

El slot comienza con tres ejemplos **comentados** (abrir el drawer en cada agregado, reaccionar a `cart_loaded` y ocultar las líneas de regalo gratis), así que un script de Initialization sin tocar no hace nada. Descomenta uno para probarlo, o reemplázalos.

La forma natural para este slot es un **registro único sin eventos involucrados**: registra el comportamiento una vez y deja que el carrito lo aplique a partir de entonces. Ocultar las líneas de regalo gratis del drawer, sin cambiar el total, es el ejemplo incluido de eso:

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

[`registerLineTransform`](/es/aftersell/cart/sdk-hooks#registerlinetransform) se ejecuta para cada línea a medida que se renderiza, y `setHidden` es solo de visualización, así que la línea permanece en el carrito y sigue contando para el total, simplemente no se muestra en el drawer. Consulta [Ocultar y reetiquetar líneas del carrito](/es/aftersell/cart/sdk-use-case-hide-lines) para ver más de lo que puede hacer una transformación.

Las acciones que leen el carrito van dentro 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');
});
```

Acceder al DOM del carrito requiere la misma espera, y necesita [`shadowRoot`](/es/aftersell/cart/sdk-overview#shadowroot): el carrito se renderiza dentro de un shadow root, así que `document.querySelector` no puede ver nada dentro del drawer.

<Tip>
  ¿Necesitas ramificar según mercado, país o moneda **antes** de que el carrito se cargue? Lee [`context`](/es/aftersell/cart/sdk-overview#context) en su lugar. Está disponible de forma síncrona, sin necesidad de `ready()`, así que puedes omitir por completo el registro de handlers para compradores a los que una regla no aplica.
</Tip>

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

El script de **On cart update** se ejecuta cada vez que el carrito cambia. Es un envoltorio bloqueado alrededor de una suscripción a `cart_updated`, así que solo editas el cuerpo, y tu código recibe el `cart` actualizado.

Este slot es para reglas que deben **reevaluarse en cada cambio del carrito**. Un umbral de regalo gratis es el caso clásico (gasta \$75 y obtén un tote gratis) porque la respuesta depende del contenido actual y nada más puede avisarte cuando cambia:

```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">
  ### Mantener el carrito en un estado deseado
</div>

La línea `if (shouldHaveGift === hasGift) return;` es lo que hace esto seguro, y se generaliza a todo script que mantiene el carrito en un estado deseado. Este slot tanto reacciona a los cambios del carrito como los provoca, así que cada `addItem` o `removeItem` vuelve a entrar en él. Describe el estado que quieres, compáralo con el estado que tienes y retorna temprano cuando ya coinciden, de modo que el handler converja tras una sola pasada en lugar de entrar en bucle. Consulta [las dos reglas](/es/aftersell/cart/sdk-events#the-two-rules) para ver la versión sin protección que debes evitar y por qué el payload es de solo lectura.

En una tienda más lenta también vale la pena mantener un flag de operación en curso a nivel de módulo, para que dos cambios rápidos no puedan iniciar ambos un add antes de que el primero termine.

<Note>
  `cart_updated` se dispara solo en cambios **posteriores** a la primera carga ([temporización de eventos](/es/aftersell/cart/sdk-events#cart_updated)), así que un script en este slot no reconciliará un carrito que ya califica cuando la página se carga. Para una versión que maneja ambos casos, suscríbete a `cart_loaded` y `cart_updated` con la misma función desde el slot de **Initialization**. Consulta [Agregar automáticamente un regalo gratis en un umbral](/es/aftersell/cart/sdk-use-case-free-gift).
</Note>

<div id="when-a-script-breaks">
  ## Cuando un script falla
</div>

Cada slot se ejecuta en su propio sandbox, así que un script de **Initialization** roto no puede impedir que **On cart update** se ejecute, y ninguno puede romper el carrito en sí.

Dentro de un slot, sin embargo, la ejecución **se detiene en el primer error**. Todo lo que está debajo de esa línea se omite, lo que significa que cualquier `configure`, `events.on` o `hooks.register*` más abajo nunca se registra. Esa es la explicación habitual de "mi handler nunca se dispara" cuando el código parece correcto.

El carrito indica la línea que falla en la consola del navegador, y cada slot se ejecuta bajo su propio nombre de archivo (`aftersell-cart-init.js` y `aftersell-cart-cart-update.js`), así que puedes abrir cualquiera desde el panel Sources de DevTools y establecer breakpoints. Consulta [Depuración](/es/aftersell/cart/sdk-overview#debugging) para ver los mensajes exactos, y para el canal de depuración que captura fallos de hooks que se mantienen fuera de la consola.

Como `cart_loaded` [se reproduce para suscriptores tardíos](/es/aftersell/cart/sdk-events#cart_loaded), el orden de registro nunca importa. La estructura más segura es registrar todo primero y hacer el trabajo arriesgado dentro de los handlers, donde un throw queda aislado a ese handler.

<div id="where-to-go-next">
  ## Adónde ir después
</div>

* **[Cart SDK](/es/aftersell/cart/sdk-overview)**: los scripts personalizados son la forma de ejecutar código del SDK. Consulta las referencias de [configure](/es/aftersell/cart/sdk-configure), [events](/es/aftersell/cart/sdk-events), [actions](/es/aftersell/cart/sdk-actions) y [hooks](/es/aftersell/cart/sdk-hooks) para ver la superficie completa, el [objeto cart](/es/aftersell/cart/sdk-cart-object) para la forma de lo que reciben los handlers, y los [casos de uso](/es/aftersell/cart/sdk-use-cases) para snippets listos para usar.
* **[Bloques de código personalizado](/es/aftersell/cart/custom-code-blocks)**: para agregar marcado al carrito. Ten en cuenta que el modo HTML del bloque Custom code **no** ejecuta JavaScript; usa scripts personalizados (o el modo React del bloque) para la lógica.
