Skip to main content
Actions read and change the cart. They live under window.aftersell.cart.actions.
Actions run after the cart is ready, inside ready() or an event handler.
Before the cart loads, actions are stubs. Each one logs a console warning naming the action, for example cart.actions.addItem() called before the cart loaded, and does nothing. The async actions still resolve a Promise, so a .then() chain runs normally rather than throwing; getCart() returns null and formatMoney() returns an empty string.Nothing breaks if you call one too early, but nothing happens either. Watch the console for that warning when an action appears to do nothing.

Every action

Calling an action from a cart_updated handler can loop. Read the two rules first.

Drawer

open and close

Open or close the cart drawer. Both are synchronous and take no arguments.

Reading

getCart()

Returns the current cart object, or null before it has loaded. The result is a copy, so mutating it won’t change the real cart.
Because it’s a snapshot, don’t hold on to the result; read it again each time you need current data. In an event handler you already have the fresh cart as the payload, so getCart() is redundant there.

formatMoney(cents)

Formats a minor-unit amount using your store’s money format. Every price in the SDK is in cents, so this is how you turn one into something you can display.
Override the format with configure({ money_format }).

Changing the cart

The item actions identify a line by its Shopify key, not by variant ID, because a cart can hold the same variant on several lines with different properties. Read it from getCart().items[n].key.

addItem(variantId, quantity?)

Adds a variant to the cart. quantity defaults to 1. Resolves once the cart has settled.
Adding a variant already in the cart increases that line’s quantity rather than creating a second line, as long as the existing line has no line item properties. A line carrying properties is a distinct line, so you get a new one.

removeItem(key)

Removes a line entirely.

updateItemQuantity(key, quantity)

Sets a line’s quantity. Passing 0 removes the line.
That second example is safe to run from cart_updated because the > 1 check is false on the second pass. See the two rules.

replaceLineVariant(key, variantId)

Swaps a line’s variant while keeping its quantity and properties. Useful for a size or flavor switcher inside the cart.
The line’s selling plan resets on a swap. A subscription line becomes a one-time purchase unless you reapply a plan.
The swap is an add followed by a remove, not an edit in place, so the result is a new line: it gets a new key and lands at the end of the cart. Re-read getCart() afterwards rather than reusing the key you passed in.

Refreshing

refresh()

Refetches the cart from Shopify. Use it after something outside the SDK changed the cart and the drawer didn’t notice.
Most of the time you don’t need this, since Aftersell already listens for Shopify’s standard cart events and refetches on its own. Reach for it when a custom integration bypasses those.

visualRefresh()

Re-runs the render transforms without refetching the cart from Shopify. You rarely need it: registering (or unregistering) a line transform, comparator, enricher, or either subscription hook triggers one for you. Only the two add-to-cart hooks don’t, since they change nothing already on screen. Reach for it when something a transform depends on changes but the cart itself hasn’t:

Notes and edge cases

  • Async actions resolve when the change settles. Awaiting one lets you sequence work after the cart has actually updated.
  • getCart() returns a copy. Mutating it does nothing to the real cart.
  • There’s no action for discount codes. Applied codes are readable on the cart (discountCodes, totalDiscount) and per line (discountAllocations); shoppers apply them through the Discount code block.
  • There’s no action for cart attributes or notes. Attributes are readable on the cart object; shoppers write notes through the Notes block.
  • To hide a line rather than remove it, use registerLineTransform. Removing changes the shopper’s total; hiding doesn’t.

Where to go next

  • Cart object: what getCart() hands back.
  • Events: when to run these actions.
  • Hooks: change how a line renders instead of changing the cart.
  • Use cases: complete solutions to common requests.