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

# Track add-to-cart in a third-party tool

> Send Aftersell Cart events to Klaviyo, Triple Whale, GA4, or any analytics pixel using the Cart SDK event bus.

Aftersell handles add-to-cart itself, which means analytics tools that watch Shopify's default cart requests may not see it. Subscribing to the SDK's events restores tracking, and gives you a cleaner payload than scraping the Ajax API.

This is the most common thing merchants use the SDK for.

## The pattern

Every integration is the same three lines: subscribe to an event, read the payload, forward it to your tool.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('item_added', (payload) => {
  myAnalytics.track('Added to cart', {
    variantId: payload.item.variantId,
    title: payload.item.title,
    quantity: payload.item.quantity,
    value: payload.item.finalLinePrice / 100, // SDK prices are in cents
  });
});
```

Paste it into **Cart settings → Custom script → Initialization**. Subscribing is a set-up call, so it's safe at the very top, so you don't need to wait for the cart to load.

## Klaviyo

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('item_added', (payload) => {
  const state = window.aftersell.cart.actions.getCart();
  if (!state) return;

  window._learnq ??= [];
  window._learnq.push(['track', 'Added to Cart', {
    $value: state.totalPrice / 100,
    AddedItemProductName: payload.item.productTitle,
    AddedItemProductID: payload.item.productId,
    AddedItemVariantID: payload.item.variantId,
    AddedItemQuantity: payload.item.quantity,
    AddedItemPrice: payload.item.finalLinePrice / 100,
    ItemNames: state.items.map((line) => line.productTitle),
    CheckoutURL: `${window.location.origin}/cart`,
  }]);
});
```

Make sure [Klaviyo onsite tracking](https://help.klaviyo.com/hc/en-us/articles/4425956184731) is installed first. This script only fires the event; it doesn't load Klaviyo.

## Triple Whale

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('item_added', (payload) => {
  window.TriplePixel('AddToCart', {
    item: payload.item.variantId,
    q: payload.item.quantity,
  });
});
```

## Google Analytics 4

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('item_added', (payload) => {
  const line = payload.item;
  window.gtag('event', 'add_to_cart', {
    currency: window.aftersell.cart.actions.getCart().currency,
    value: line.finalLinePrice / 100,
    items: [{
      item_id: String(line.variantId),
      item_name: line.productTitle,
      item_variant: line.variantTitle,
      price: line.finalLinePrice / line.quantity / 100,
      quantity: line.quantity,
    }],
  });
});
```

## Other events worth tracking

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Cart viewed.
window.aftersell.cart.events.on('cart_opened', () => {
  myAnalytics.track('Cart viewed');
});

// Item removed.
window.aftersell.cart.events.on('item_removed', (payload) => {
  myAnalytics.track('Removed from cart', { variantId: payload.item.variantId });
});

// Checkout intent: fires just before the browser navigates.
window.aftersell.cart.events.on('checkout', () => {
  const state = window.aftersell.cart.actions.getCart();
  navigator.sendBeacon('/my-endpoint', JSON.stringify({
    event: 'checkout_started',
    value: state ? state.totalPrice / 100 : 0,
  }));
});
```

<Warning>
  Use [`navigator.sendBeacon`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon) in a `checkout` handler. The page is about to unload, and a normal `fetch` may be cancelled mid-flight. You also **can't cancel checkout** from this handler; it's a notification, not a gate.
</Warning>

## Things to get right

* **Prices are in cents.** Divide by 100 for tools that expect a decimal amount. [`formatMoney`](/aftersell/cart/sdk-actions#formatmoneycents) is for display only, so don't send a formatted string to an analytics tool.
* **A quantity bump isn't `item_added`.** Going from 1 to 3 on an existing line fires `cart_updated`, not `item_added`. If your tool needs to see that, diff against the previous state in a `cart_updated` handler.
* **Don't track from `cart_updated` if you mean "added".** It fires on every change, including removals and quantity edits, so you'll over-report.
* **Check for double-counting.** If your tool already captures add-to-cart some other way, this script will report it twice. Verify in the tool's live view before going live.

## Testing it

Add a `console.log` alongside your tracking call, then open the browser console and add a product:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('item_added', (payload) => {
  console.log('[tracking] item_added', payload.item.title);
  // …your tracking call
});
```

If the log doesn't appear, the script isn't running, so check it saved to the **Initialization** slot. If the log appears but the tool shows nothing, the problem is in the tool's payload format, not the SDK.

## Where to go next

* **[Events](/aftersell/cart/sdk-events)**: every event and when it fires.
* **[Cart object](/aftersell/cart/sdk-cart-object)**: every field you can send.
* **[Cart analytics](/aftersell/cart/analytics)**: the reporting Aftersell provides out of the box.
