Cart drawer public API (SectionStoreCart)
JavaScript reference for developers. Open the drawer, change the cart, block actions and listen for events.
Every page where the drawer runs has a JavaScript API at window.SectionStoreCart. Use it to open the drawer, read or change the cart, block an action, or listen for changes. This article is for developers. You don't edit any Section Store code.
To see the reference in your browser, open your storefront, open the console and run SectionStoreCart.help(). The current version is 1.
Quick start
// Wait for the first cart to load, add a product, open the drawer
await SectionStoreCart.ready;
await SectionStoreCart.addItem({ id: 40000000000000, quantity: 1 });
SectionStoreCart.open();
// React to cart changes from any source
window.addEventListener("section-store:cart:updated", (event) => {
console.log(event.detail.cart.item_count, "items via", event.detail.source);
});
// Block checkout until the shopper accepts terms
SectionStoreCart.onBeforeCheckout(({ cart }) => cart.attributes.terms_accepted === "yes");
Drawer
| Method | Returns | What it does |
|---|---|---|
open() |
void | Opens the drawer |
close() |
void | Closes the drawer |
toggle() |
void | Opens when closed, closes when open |
isOpen() |
boolean | Whether the drawer is open |
Reading the cart
| Member | Returns | What it does |
|---|---|---|
ready |
Promise | Resolves with the API once the first cart has loaded |
getCart() |
cart or null | A copy of the cached Shopify cart |
getItemCount() |
number | Total quantity in the cart |
getTotalPrice() |
number | Cart total in cents |
refresh() |
Promise | Fetches the cart from Shopify again |
subscribe(fn) |
function | Calls fn(cart) now and on every change. Call the returned function to stop. |
Changing the cart
Each method returns a Promise with the updated cart. The drawer redraws by itself.
| Method | What it does |
|---|---|
addItem(item) |
Adds one item. item = { id, quantity, properties, selling_plan }, where id is the variant ID. |
addItems(items) |
Adds several items in one request |
addFormData(formData) |
Adds from a product form's FormData |
updateLine(key, qty) |
Sets a line's quantity. key is the line's key from the cart. |
removeLine(key) |
Removes a line |
clear() |
Empties the cart |
applyDiscount(code) |
Adds a discount code. An invalid code doesn't throw. It comes back in cart.discount_codes with applicable: false. |
removeDiscount(code) |
Removes a discount code |
setNote(text) |
Sets the order note |
setAttributes(obj) |
Sets cart attributes. Leave __section_store_cart_managed alone. |
Adding through the API doesn't open the drawer. Call open().
Hooks that can cancel an action
Each hook runs before the action. Return false to stop it. Each one returns a function that removes it.
| Hook | Your function receives | Stops |
|---|---|---|
onBeforeOpen(fn) |
nothing | The drawer opening |
onBeforeClose(fn) |
nothing | The drawer closing |
onBeforeAddToCart(fn) |
{ form, formData } |
A theme product form going through the drawer |
onBeforeCheckout(fn) |
{ checkoutUrl, cart } |
The checkout button |
What happens on an error or a Promise differs:
- Open, close and add to cart: a thrown error is logged and the action goes ahead.
- Checkout: a thrown error blocks checkout, and its message shows in the drawer. A returned Promise blocks it too.
While any onBeforeCheckout hook exists, the express checkout buttons hide. A wallet click can't be stopped.
// Keep the drawer closed on the cart page
const stop = SectionStoreCart.onBeforeOpen(() => location.pathname !== "/cart");
// later: stop();
Line rules
Both functions must answer synchronously. A function that returns a Promise throws "Cart integration callbacks must return synchronously".
| Method | Your function receives | It returns |
|---|---|---|
registerLineRules(fn) |
{ item, cart } |
{ allowRemove, allowQuantityChange } or undefined |
onBeforeUpdateLines(fn) |
{ cart, updates } |
Updates with linked line quantities, false, or undefined |
registerLineRuleslocks a line's controls. A rule that fails locks its line.onBeforeUpdateLinescan add linked changes. It must keep the updates it received. Returningfalsestops the change.- Each returns a function that removes it.
Events
All events fire on window. The data is in event.detail.
| Event | detail | When |
|---|---|---|
section-store:cart:ready |
{ cart } |
The first cart has loaded |
section-store:cart:updated |
{ cart, source } |
The cart changed. source is "internal" or "external". |
section-store:cart:item-added |
{ cart, lines } |
Lines appeared or grew |
section-store:cart:item-removed |
{ cart, lines } |
Lines disappeared or shrank |
section-store:cart:opened |
{ cart } |
The drawer opened |
section-store:cart:closed |
{ cart } |
The drawer closed |
section-store:cart:discount-applied |
{ cart, codes } |
New discount codes were applied |
section-store:cart:checkout-clicked |
{ cart, checkoutUrl }, plus wallet for express buttons |
The shopper clicked checkout |
section-store:cart:error |
{ error } |
A cart action failed. Its Promise rejects with the same message. |
Utilities
| Member | Returns | What it does |
|---|---|---|
formatMoney(cents) |
string | Formats an amount with the store's money format |
version |
string | The API version |
help() |
void | Prints the reference in the console |
Good to know
- The
cartobject is Shopify's own cart JSON. Prices are in cents. - The drawer takes over your theme's add-to-cart forms and cart links. It also watches cart calls from other scripts. Most themes and apps stay in sync with no code.
- Failed actions reject with Shopify's message when there is one.
Check the drawer from the console
typeof SectionStoreCart // "object" means the drawer script loaded
SectionStoreCart.version // "1"
SectionStoreCart.getCart() // what the drawer has in the cart
SectionStoreCart.isOpen()
// Log every cart event
["ready","updated","item-added","item-removed","opened","closed","discount-applied","checkout-clicked","error"]
.forEach(n => window.addEventListener("section-store:cart:" + n, e => console.log(n, e.detail)));
If typeof SectionStoreCart returns "undefined", the drawer didn't load on that page. Check that your store has Plus, that the cart is Active and that the app embed is on in the theme you are viewing.
Related
- Add custom HTML to the cart drawer
- Choose when the cart drawer opens
- Why ShipStation shows __section_store_cart_managed as a customer note
Also searched as: cart drawer api, sectionstorecart, section store cart api, javascript api, js api, public api, cart drawer javascript, cart drawer events, cart events, cart updated event, section-store:cart, open cart drawer with code, open drawer programmatically, close cart drawer, trigger cart drawer, add to cart with javascript, addItem, add item api, update line quantity, remove line, clear cart, apply discount code with code, discount code api, set cart note, cart attributes, setAttributes, onBeforeCheckout, block checkout, prevent checkout, terms checkbox checkout, onBeforeAddToCart, hooks, cancel action, listen for cart changes, cart change listener, subscribe to cart, integrate with another app, developer, help(), console, debug cart drawer, formatMoney, item_count, checkoutUrl, window.SectionStoreCart, registerLineRules, onBeforeUpdateLines, onBeforeOpen, lock cart line
Did this answer your question?