AJAX cart setup
Turn on AJAX cart mode, point the app at your theme's cart selectors, and run a custom add-to-cart callback.
When a customer adds, removes, or changes the quantity of something in their cart, you usually want the cart and your upsell widgets to update right away — without the page reloading. That is exactly what AJAX cart mode does. This guide is the deep dive on the Cart page section of Settings: what each field means, how to find the right selectors for your theme, how the add-to-cart callback works, and how to fix the most common setup problems.
What AJAX cart mode does
AJAX cart mode lets cart updates happen without a full page reload. When it is on, the app intercepts cart changes and refreshes the cart contents — and any upsell widgets tied to the cart — in place. This keeps the cart subtotal, line items, progress bars, and widgets in sync after every add, remove, or quantity change, so a customer never sees a stale total or a widget that hasn't caught up.
The setting that controls this is Enable AJAX (enableAjaxCart). It is off by default. With it off, the app relies on a normal page reload to show updated cart state, which is the safe choice for themes that already handle their own cart updates (more on that below).
AJAX cart mode is about the app keeping itself in sync with your theme's cart. It does not replace your theme's cart — for that, see Llama Cart further down this page.
The two required selectors
When Enable AJAX is on, the app needs to know where on the page your theme draws the cart, so it can update those regions in place. You provide that with two CSS selectors. Both are required whenever AJAX is enabled.
| Setting | Field | Default | What it points to |
|---|---|---|---|
| Cart items Container Selector | itemsContainerSelector | .cart-items | The element that wraps your cart line items (the list of products in the cart). |
| Cart Footer Selector | cartFooterSelector | .cart__footer | The element that wraps your cart footer — subtotal, taxes/shipping note, and the checkout button. |
These selectors tell the app which parts of the rendered cart page to re-render when something changes. If they point at the wrong elements — or at nothing — the app can't update the cart in place, and you'll see the symptoms described in Edge and complex cases.
The defaults .cart-items and .cart__footer match Shopify's Dawn theme. They will not necessarily match your theme. Always verify the selectors against your own cart template before relying on them.
How to find the right selectors for your theme
Every theme structures its cart page a little differently, so the safest way to set these is to inspect your live cart template.
Open your cart page
Add a product to your cart and go to /cart on your storefront (or open the cart page directly in your browser).
Inspect the cart items wrapper
Right-click the list of cart line items and choose Inspect. Find the element that wraps all the line items (not a single row). Note its class or id, and write it as a CSS selector — for example .cart-items, #main-cart-items, or .cart__items.
Inspect the cart footer
Right-click near the subtotal / checkout button and choose Inspect. Find the wrapper around the subtotal and checkout button, and note its selector — for example .cart__footer, .cart-footer, or .totals.
Enter both selectors and save
Paste the items-container selector into Cart items Container Selector and the footer selector into Cart Footer Selector, then Save.
Common selectors by theme family
These are good starting points, but always confirm against your own theme since merchants and developers often rename classes:
| Theme | Likely items container | Likely footer |
|---|---|---|
| Dawn (and the app defaults) | .cart-items | .cart__footer |
| Horizon and other Online Store 2.0 themes | a cart-items-style wrapper or #main-cart-items | a cart__footer-style wrapper |
| Custom / heavily modified themes | inspect the template — selectors are often renamed | inspect the template |
For an Online Store 2.0 theme, the cart markup usually lives in sections/main-cart-items.liquid and sections/main-cart-footer.liquid (or similar). If you have theme code access, opening those files is the fastest way to confirm the exact wrapper class. For custom themes, there is no shortcut — inspect the rendered page and use whatever wrapper your developer used.
The add-to-cart callback
Sometimes you want your own JavaScript to run every time a product is added to the cart — to fire an analytics event, open a cart drawer, or show a toast. The app supports this with two settings:
| Setting | Field | Default | What it does |
|---|---|---|---|
| Enable Callback Function | useAddToCartCallback | false (off) | Turns the custom callback on. While off, your callback code is ignored. |
| Callback JavaScript code | onAddToCartCallback | empty | The JavaScript that runs whenever a product is added to the cart. |
How the callback behaves:
- No
<script>tag. Paste plain JavaScript only — do not wrap it in<script>...</script>. The app injects and runs it for you. - Runs on every add-to-cart. Your code executes each time a product is added to the cart through the app's flow.
- You get an
itemvariable. Inside your callback, a variable nameditemholds the data for the product that was just added. Use it to read the product's details for analytics or messaging.
Example callbacks
Fire a custom analytics event with the added product:
// `item` is the product that was just added to the cart
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'app_add_to_cart',
product: item,
});Show a quick confirmation toast:
const toast = document.createElement('div');
toast.className = 'app-toast';
toast.textContent = 'Added to cart';
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 2500);Open the theme's cart drawer after an add (selector depends on your theme):
// Many Online Store 2.0 themes expose the drawer as a custom element
document.querySelector('cart-drawer')?.classList.add('active');
document.querySelector('cart-drawer')?.removeAttribute('hidden');Callback code is your responsibility — the app does not sanitize or validate it. A callback that throws an error can interrupt the add-to-cart flow and stop products from being added. Always test your callback on a development or unpublished theme first, and keep it defensive (for example, use optional chaining like ?. and guard against missing elements).
Relationship to Llama Cart
The selectors and AJAX setting apply to your theme's cart page. They matter most when customers use the standard theme cart.
Llama Cart is the app's own AJAX cart drawer. When you enable Llama Cart, it replaces the theme cart with the app's drawer, and the drawer handles its own rendering and updates. In that setup, the theme cart selectors are about your theme's /cart page rather than the Llama Cart drawer itself.
| Your setup | What matters |
|---|---|
| Theme cart (Llama Cart off) | Enable AJAX, Cart items Container Selector, and Cart Footer Selector point the app at your theme's cart so it can update line items, the footer, and widgets in place. |
| Llama Cart drawer (Llama Cart on) | The app's drawer replaces the theme cart and manages its own rendering. The theme cart selectors describe the underlying theme /cart page rather than the drawer. |
The Enable Llama Cart toggle lives in the app's shop settings, separate from the Cart page section. To customize the drawer itself, see Widgets and Llama Cart.
Price formatting in the AJAX-updated cart
When the app re-renders the cart, prices are formatted according to your Price Decimal Scale setting (priceDecimalScale), found in the Global section of Settings. This is worth knowing here because it controls how every price looks in the cart the AJAX flow updates.
| Option | Field value | Effect |
|---|---|---|
| Enforce 2 Decimal Places | FIXED_TWO (default) | Always shows two digits — for example, 2 renders as 2.00. |
| Trim Unnecessary Zeros | DYNAMIC | Removes trailing zeros — for example, 2.00 renders as 2. |
This value also syncs to the global app metafield, so storefront widgets read it directly without an extra API call — keeping the AJAX-updated cart and your widgets formatting prices the same way. Full details are in Cart & checkout settings.
Edge and complex cases
Recipe: enable AJAX, set selectors, verify, add a drawer callback
Enable AJAX
In Settings → Cart page, turn on Enable AJAX.
Set both selectors
Inspect your cart page and enter the wrapper selectors into Cart items Container Selector and Cart Footer Selector. On Dawn the defaults .cart-items and .cart__footer usually work; on other themes use what you found by inspecting.
Save
Click Save in the sticky save bar. Unsaved changes do not apply to your storefront.
Verify with a test add-to-cart
On your storefront, add a product to the cart, then change its quantity and remove it. Confirm the line items, subtotal, and any upsell widgets update without a full page reload. If they don't, revisit your selectors in Edge and complex cases.
Add a callback that opens the theme drawer
Turn on Enable Callback Function, then paste a small script into Callback JavaScript code (no <script> tag) that opens your theme's drawer — for example:
document.querySelector('cart-drawer')?.classList.add('active');Save, then add a product and confirm the drawer opens. Adjust the selector to match your theme's drawer element.
Troubleshooting
| Problem | Likely cause | Fix |
|---|---|---|
| Cart doesn't update without reload | Wrong/missing selectors, or AJAX is off | Verify Enable AJAX is on; re-inspect and correct both selectors. |
| Widgets show stale cart data | Items container selector doesn't wrap all line items | Point Cart items Container Selector at the full line-item wrapper. |
| Subtotal/footer doesn't refresh | Footer selector is wrong | Point Cart Footer Selector at the subtotal/checkout wrapper. |
| Add-to-cart stopped working after editing the callback | Callback throws an error | Turn off Enable Callback Function, confirm add-to-cart works, fix the code, re-enable. |
| Selectors worked before, now they don't | Theme update/switch renamed the markup | Re-inspect the cart page and update the selectors. |
Related
Cart & checkout settings
Configure how the app works with your theme's cart page, set global price and styling rules, and customize checkout error messages.
Restrictions & limiters with express checkout
How cart restrictions and product limiters enforce on Shop Pay, Apple Pay, Google Pay, PayPal and other express buttons.
