Why does my Add to Cart button fire twice, once from my theme and once from an app?
When your theme and an installed app each attach their own cart event listener, you can end up with double quantity increments, a cart drawer that opens twice, or duplicate analytics pings. Here's how to find the collision and fix it.
What's going on
If clicking Add to cart seems to run twice, meaning the quantity jumps by two, the cart drawer flashes open and reopens, or your analytics and pixel tools log two add-to-cart events for one click, the usual cause is that two separate scripts are listening for the same cart action and both are handling it.
This happens because Shopify themes ship their own JavaScript for handling the add-to-cart form, such as submitting it, updating the cart icon, and opening a cart drawer or notification, and many apps installed through theme app extensions or script and app-embed blocks add their own JavaScript that does something similar, often listening on the same button click, the same form's submit event, or watching for the cart to update. Neither script is aware the other exists, so when both attach a listener to the same element or event, both fire, and the action happens twice.
It isn't a Shopify platform bug, and it won't show up as an obvious setting in your theme editor. It only becomes visible in the storefront's actual behavior, which is why it often gets reported as a vague complaint about the cart acting strangely rather than traced back to its real cause.
Why it happens
Shopify themes and apps are built independently, and the platform doesn't enforce a single shared cart-event system that every script must use. Reference themes have their own internal pattern for signaling that the cart changed, but installed apps aren't required to hook into that same pattern rather than attaching their own listeners directly to cart forms or buttons.
It gets worse with dynamic cart drawers and partial page re-renders: when a section reloads after a cart update, any initialization code that runs again, whether from the theme or an app, can re-attach a fresh event listener to an element that already has one, silently doubling the handler count without throwing any error.
5 ways to fix it
Confirm both scripts are actually binding to the same action
Open DevTools on the storefront, select the add-to-cart button or form in the Elements panel, and check its listeners (Chrome's console exposes this via the getEventListeners() helper). You'll usually find two separate handlers on the same element or form: one from the theme's own cart JavaScript, and one added by an app's script tag or theme app extension block. Confirming exactly which two scripts and which DOM node are involved tells you what to fix instead of guessing at a cause.
Guard your own listener so it can't attach twice
If you or a developer control the theme code, wrap the binding in a check so it only runs once, for example testing a data attribute on the element before calling addEventListener, then setting that attribute immediately after binding. This matters most when a section re-renders after a cart change, since re-running the same initialization code can quietly attach a second listener to an element that already has one.
Have both scripts react to one shared cart event instead of the raw click or submit
Shopify's reference themes generally dispatch a custom event after the cart has actually changed, rather than every component listening to the raw form submit or button click directly. If your app's script and your theme both hook into that same downstream event instead of each independently intercepting the add-to-cart action, the duplication goes away at the source instead of needing a workaround.
Turn off the redundant feature if an app is duplicating something your theme already does
If an app adds its own cart drawer, upsell popup, or add-to-cart confirmation, check your theme customizer for the equivalent built-in feature (cart notification, cart drawer type, and similar settings) and disable it there. Running both the theme's native cart UI and an app's competing version at the same time is a common cause of a click seeming to fire twice, and switching one off is a no-code fix you can do yourself.
Ask the app's support team what it hooks into
The app's developers already know which elements and events their script binds to. Asking support which cart events or selectors the app listens on lets you (or your developer) namespace your own theme customizations differently, so the two scripts stop reacting to the same generic event. It's usually faster than reverse-engineering the collision yourself.
Bottom line
This is a collision between two independently written scripts, not a bug in Shopify itself, so there's no single setting that fixes it for every store. Most merchants resolve it with a small, targeted change: guarding against duplicate listener binding, or getting both scripts to react to one shared cart event instead of each intercepting the action separately. If you're not comfortable editing theme JavaScript, this is worth handing to a developer or your theme or app's support rather than searching for another app to install, since no app reliably fixes an event collision that's specific to your particular theme-and-app combination.
Browse the rest of the problem library, run a free storefront scan to catch issues like this automatically, or email us and we'll work out a custom solution for it.