When your cart drawer is not updating, the drawer has stopped re-rendering from the current cart state. The count, the line items or the total are out of sync with what Shopify actually holds in the cart. The usual causes are narrow: the Ajax add/change request isn’t refreshing the drawer’s section, a JavaScript error is halting the update mid-way, two apps or scripts are both trying to control the cart, or custom theme code isn’t listening for the right cart-update event. You diagnose it the same way every time — open the browser console, watch the cart Ajax responses, and see whether the drawer redraws when the cart changes. Below is how the flow is supposed to work, why a broken drawer costs sales, and how to fix each cause without breaking the rest of your cart.
Diagnosis: how the Ajax cart and drawer should work
On a modern Shopify theme, the cart drawer is driven by the Ajax Cart API — a set of
endpoints under /cart/*.js that return JSON. When a shopper adds an item, the theme POSTs
to /cart/add.js; when they change a quantity, it POSTs to /cart/change.js. Each call
returns the updated cart object. The drawer’s job is to take that fresh state and redraw
itself: the item count, the line items, the subtotal.
The clean way themes do this is the Section Rendering API. Instead of hand-patching the
DOM, the theme asks Shopify to re-render the cart-drawer section server-side and swap the new
HTML into the page. You’ll see it as a sections= parameter on the Ajax request (for example
/cart/add.js with a sections field), and a sections object in the JSON response
containing rendered HTML. The drawer replaces its innerHTML with that markup, so the display
always matches the true cart.
So the correct chain is: cart change → Ajax request → updated cart (+ rendered section) → drawer re-renders. A drawer that “won’t update” has a break somewhere in that chain. The value of knowing the chain is that it tells you exactly where to look.
Why it matters: a broken drawer loses the sale
The cart drawer is the moment of commitment. A shopper clicks add-to-cart expecting instant confirmation — the drawer slides open, the count ticks up, their item is there. When it doesn’t, the shopper’s read isn’t “minor bug”; it’s “did that work?” They click again, now you have a duplicate line, or they assume it failed and leave. Either way you’ve injected doubt at the exact second they decided to buy.
A stale drawer also breaks everything downstream: free-gift thresholds that don’t trigger, upsells that show the wrong state, a subtotal that argues with checkout. If the count is right but the money is wrong, that’s a different and worse problem — see Shopify cart price different from checkout. And if shoppers are adding to cart but the flow silently fails afterward, the pattern in add to cart but no sales is worth reading next.
The likely causes
The Ajax request isn’t refreshing the section. The add/change call succeeds, but the
theme never requests (or never injects) the re-rendered cart section. The cart object updated
server-side; the drawer’s HTML didn’t. Common after a theme edit that removed the sections
handling, or a custom add-to-cart button that POSTs to /cart/add.js but forgets to trigger
the drawer refresh.
A JavaScript error halts the update. The drawer’s update runs in a callback after the Ajax response. If any earlier line throws — a null element, a bad selector, an app script that errored first — the callback never finishes and the drawer freezes on its old state. One uncaught error anywhere on the page can take the whole update path down with it.
Two apps or scripts control the cart. Upsell, bundle, sticky-cart, discount and “cart upgrade” apps frequently replace or wrap the drawer. Install two and they fight: both listen for add-to-cart, both try to redraw, and they overwrite each other’s DOM or race on the same event. This is one of the most common conflict zones on Shopify — app conflicts covers the general pattern, and a drawer is a textbook symptom.
Custom code isn’t listening for cart-update events. Themes and apps broadcast a change via
events (commonly a cart:updated / cart-update custom event, or the Pub/Sub API on newer
Dawn-based themes). Custom code you added — a progress bar, a gift message, a badge — must
subscribe to that event to redraw. If it reads the cart once on page load and never listens,
it will always show a stale number.
Bundled or line-item items render wrong. Bundles and items with line-item properties add lines the drawer’s template may not handle — a component product with no image, a “hidden” bundle child, a property that should be shown or suppressed. The cart is correct; the drawer’s markup just mishandles those specific lines.
Caching. A CDN or aggressive theme cache can serve stale cart-drawer HTML, or a browser can hold an old script. Rarer, but it explains “it’s fixed for me but not for customers.”
How to diagnose it
| Step | What to do | What it tells you |
|---|---|---|
| 1. Open the console | DevTools → Console, then add an item | A red error at add-to-cart = a script is halting the update |
| 2. Watch the Network tab | Filter to cart, add/change an item | Confirms /cart/add.js / /cart/change.js fire and return the new cart |
| 3. Inspect the response | Open the Ajax response JSON | If item_count/items are correct here but the drawer is wrong, it’s a render/event bug, not a cart bug |
4. Check for sections | Look for a sections param/response | Missing = the theme isn’t re-rendering the drawer section |
| 5. Isolate on a duplicate theme | Duplicate the theme, disable apps one at a time, re-test | The disable that fixes it names the conflicting app |
| 6. Read the theme cart JS | Find the drawer/cart component script | Confirms whether it listens for cart-update events and re-renders |
The single most useful signal is step 3: if the Ajax response holds the correct cart but the drawer shows something else, the cart is fine — your bug is in rendering or events. That one check splits the problem in half and stops you fixing the wrong layer.
How to fix each cause
- Section not refreshing → make the add/change request include the cart-drawer section in
its
sectionsparameter, and swap the returned HTML into the drawer on response. On Dawn-based themes this is what the cart component already does; a custom button needs to call the same update, not just/cart/add.js. - JavaScript error → read the stack trace, fix the throwing line (or the app that owns it), and confirm the update callback now completes. Don’t wrap the error to hide it — find why it throws.
- App conflict → keep the app that owns the cart experience and remove or reconfigure the other, or have the two coordinate on the same event. Two scripts must not both redraw the drawer.
- Missing event listener → subscribe your custom code to the theme’s cart-update event (or
the Pub/Sub
cart-updateevent) so it redraws whenever the cart changes, instead of reading once on load. - Bundle/line-item rendering → fix the drawer template to handle those lines — show or hide component products, guard against missing images, and render line-item properties correctly.
- Caching → confirm you’re not caching authenticated cart HTML, bust the theme asset version, and test in a private window to rule out a stale local script.
Common mistakes
- Editing the live theme. Debugging cart JS on the published theme risks breaking checkout for real shoppers. Always duplicate the theme and work on the copy.
- Guessing at the cause. “Probably an app” is not a diagnosis. The console and the Ajax response tell you which layer is broken — check before you change anything.
- Patching the DOM by hand. Manually setting the count with JavaScript instead of re-rendering from cart state hides the bug and drifts out of sync again on the next change.
- Ignoring the second app. If two cart apps are installed, the fix is usually to stop them fighting — not to add a third script on top.
- Assuming the cart is wrong. Nine times out of ten the cart object is correct and only the drawer’s display is stale. Verify the Ajax response before you touch the cart logic.
When to get a developer
If the Ajax response is correct but the drawer stays stale after you’ve checked events and section rendering, or two apps are clearly fighting over the cart and you can’t drop either, that’s the point to bring in someone who reads theme cart internals daily. A developer can trace the exact break in the render chain, make conflicting scripts coordinate, and harden the drawer so it always redraws from real cart state — which is the kind of work our Shopify development service handles. If you’re not sure whether it’s a theme bug or an app conflict yet, a free profit audit will pin down the layer before anyone touches code.
Cart drawer misbehaving? Send us your store URL and the steps to reproduce — we’ll isolate whether it’s a theme bug or an app conflict and fix it without breaking the rest of your cart. See our Shopify development service or get a free profit audit.