🛒 AutoCart Docs

Events API

Reference for the AutoCart DOM events dispatched on document when cart gifts are added, removed, or swapped.

Overview

When onAutocartUpdateCallback: true is set in Custom Settings, AutoCart dispatches CustomEvents on document after every cart gift mutation. These events let your theme or custom code react to gift changes without polling the cart API.

All events are gated behind the onAutocartUpdateCallback setting. When disabled, no events are dispatched and there is zero runtime overhead.

Events Reference

Event NameWhen it FiresCancellableevent.detail Type
autocart:readyOnce, after the first rule evaluation completes on page loadNoAutoCartResult
autocart:beforeBefore cart mutations are executed (planned changes)NoAutoCartResult
autocart:updatedAfter all mutations succeed (debounced 100ms)NoAutoCartResult
autocart:errorWhen a cart mutation failsNo{ error: unknown, result?: AutoCartResult }

All events bubble, so you can listen on document or any ancestor element.

Result Object Shape

Every event carries an AutoCartResult object in event.detail:

{
  type: "swap",           // "add" | "remove" | "swap" | "noop"
  cartToken: "c1-abc123",
  itemCount: 4,           // resulting cart item count
  cart: { ... },          // full /cart.js snapshot
  changes: [
    {
      action: "removed",
      reason: "no_longer_qualifying",
      rule: {
        id: "BOGO_SUMMER",
        title: "BOGO_SUMMER",
        scope: "cart"
      },
      variantId: 44012345678,
      productId: 8012345678,
      handle: "summer-tote",
      title: "Summer Tote Bag",
      quantity: 1,
      properties: { _autocart: true, _title: "BOGO_SUMMER" }
    },
    {
      action: "added",
      reason: "qualified",
      rule: {
        id: "FREE_SUNGLASSES",
        title: "FREE_SUNGLASSES",
        scope: "cart"
      },
      variantId: 44098765432,
      productId: 8098765432,
      handle: "free-sunglasses",
      title: "Classic Sunglasses",
      quantity: 1,
      properties: { _autocart: true, _title: "FREE_SUNGLASSES" }
    }
  ]
}

type Values

ValueMeaning
"add"Only additions in this evaluation
"remove"Only removals in this evaluation
"swap"Both additions and removals (e.g., gift replaced)
"noop"Cart evaluated but no gift changes were needed

Change Entry

Each entry in the changes array describes one cart line that was added or removed:

FieldTypeDescription
action"added" | "removed"Whether the line was added or removed
reasonstringWhy the change happened (see below)
ruleobject{ id, title, scope } of the rule that triggered the change
variantIdnumberShopify variant ID
productIdnumberShopify product ID (0 if unknown)
handlestringProduct handle
titlestringProduct title
quantitynumberLine quantity
propertiesobjectLine item properties

Reason Codes

ReasonActionDescription
qualifiedaddedRule conditions now met, gift added
no_longer_qualifyingremovedRule conditions no longer met
promotion_endedremovedRule's scheduled end date has passed
outdatedremovedRule or variant no longer exists in active rules
rule_triggeredremovedA scope="remove" rule actively removed the item
manualadded/removedCustomer selected or changed gifts in the picker dialog

Usage Examples

Listen for Gift Changes

document.addEventListener('autocart:updated', (event) => {
  const { type, changes, cart } = event.detail;
 
  if (type === 'noop') return;
 
  console.log(`AutoCart ${type}: ${changes.length} change(s)`);
 
  for (const change of changes) {
    console.log(`${change.action} ${change.title} (${change.reason})`);
  }
 
  // Refresh your mini-cart with the updated cart data
  updateMiniCart(cart);
});

Lock UI During Mutations

document.addEventListener('autocart:before', () => {
  document.querySelector('.cart-drawer').classList.add('loading');
});
 
document.addEventListener('autocart:updated', () => {
  document.querySelector('.cart-drawer').classList.remove('loading');
});

Track Removed Gifts

document.addEventListener('autocart:updated', (event) => {
  const removed = event.detail.changes.filter(c => c.action === 'removed');
 
  for (const gift of removed) {
    // The removed gift data is only available here —
    // once removed, it can't be read back from /cart.js
    console.log(`Gift removed: ${gift.title} (reason: ${gift.reason})`);
  }
});

Wait for AutoCart Ready

document.addEventListener('autocart:ready', (event) => {
  console.log('AutoCart initialized', event.detail);
  // Safe to read initial gift state
});

Debouncing

When multiple cart changes happen in rapid succession (e.g., customer adds 3 items quickly), AutoCart coalesces autocart:updated events with a 100ms debounce window. Only the final evaluation result is dispatched.

autocart:before is not debounced — it fires immediately before each mutation so your UI can show a loading state right away.

The debounce only affects autocart:updated. All other events (autocart:before, autocart:error, autocart:ready) fire immediately.

On this page