Cart Drawer Public API (SectionStoreCart)
Every store with the Section Store Cart Drawer enabled gets a small JavaScript API on window.SectionStoreCart . Use it to open the drawer, read or change the cart, block an action, or listen for cart changes from your theme or another app. No Section Store code needs editing.
To see the full reference in your browser, open your storefront, press F12 (or Cmd+Option+I), go to 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 (the drawer, your theme, another app)
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 right now |
Reading the cart
| Method | Returns | What it does |
|---|---|---|
ready |
Promise<api> | Resolves with the API once the first cart has loaded. Await it before anything else. |
getCart() |
cart | null | The cached Shopify cart. It is a copy, so you can change it without side effects. |
getItemCount() |
number | Total quantity in the cart |
getTotalPrice() |
number | Cart total in cents |
refresh() |
Promise<cart> | Re-fetches the cart from Shopify |
subscribe(fn) |
() => void | Calls fn(cart) once right away and again on every change. Call the returned function to stop. |
Changing the cart
Every method here returns a Promise with the updated cart, and the drawer redraws on its own.
| 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 the quantity of a cart line. key is the line's key from the cart, not its position. |
removeLine(key) |
Removes a cart line |
clear() |
Empties the cart |
applyDiscount(code) |
Adds a discount code. An invalid code does not 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. The drawer keeps its own __section_store_cart_managed attribute on the cart, leave it alone. |
Hooks that can cancel an action
Each hook registers a function that runs just before the action. Return false to stop it. Anything else lets it through, including a thrown error, which is logged and ignored. Each hook returns a function that removes it again.
| 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 being added through the drawer |
onBeforeCheckout(fn) |
{ checkoutUrl, cart } |
The shopper going to checkout |
// Keep the drawer closed on the cart page const stop = SectionStoreCart.onBeforeOpen(() => location.pathname !== "/cart"); // later: stop();
Events
All events fire on window . The payload is in event.detail .
| Event | detail | When |
|---|---|---|
section-store:cart:ready |
{ cart } |
The first cart has loaded |
section-store:cart:updated |
{ cart, source } |
Anything in the cart changed. source is "internal" (the drawer or this API) or "external" (your theme or another app called Shopify's cart endpoints and the drawer picked it up) |
section-store:cart:item-added |
{ cart, lines } |
Lines that appeared or grew |
section-store:cart:item-removed |
{ cart, lines } |
Lines that disappeared or shrank |
section-store:cart:opened |
{ cart } |
Drawer opened |
section-store:cart:closed |
{ cart } |
Drawer closed |
section-store:cart:discount-applied |
{ cart, codes } |
The list of discount codes on the cart changed |
section-store:cart:checkout-clicked |
{ cart, checkoutUrl } |
The shopper clicked checkout |
section-store:cart:error |
{ error } |
A cart action failed. The Promise for that action rejects with the same message. |
Utilities
| Member | Returns | What it does |
|---|---|---|
formatMoney(cents) |
string | Formats an amount with the shop's money format |
version |
string | Public API version |
help() |
void | Prints this reference in the console |
Good to know
- The
cartobject everywhere is Shopify's own cart JSON (items,item_count,total_price,attributes,note,discount_codesand so on). Prices are in cents. - Adding through the API does not open the drawer. Call
open()when you want it shown. - The drawer already takes over your theme's add to cart forms and cart links, and watches cart calls made by other scripts, so most themes and apps stay in sync without any code.
- Hooks run synchronously. A function that returns a Promise counts as allowed.
- Failed actions reject with Shopify's message when there is one (for example an out of stock variant), otherwise a short text such as "Could not add item" or "Cart line could not be found".
Check the drawer from the console
Handy when something looks off. Paste into the Console on the storefront page.
typeof SectionStoreCart // "object" means the drawer script loaded on this page
SectionStoreCart.version // "1"
SectionStoreCart.getCart() // what the drawer thinks is in the cart right now
SectionStoreCart.isOpen()
// Log every cart event for a few minutes
["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 is "undefined" , the Cart Drawer is not enabled on that theme, or the page loaded before the app embed. Check the drawer is turned on in Section Store → Cart Drawer and that the theme is the one you are viewing.