JavaScript
The browser events CartPops V2 listens to and dispatches, and how to open the drawer or keep a counter in sync from your own code.
CartPops V2 has no JavaScript object and no methods to call. Its browser surface is a small set of DOM events on document, plus the standard WooCommerce events it listens to.
Events you can dispatch
Dispatch these on document. They take no data.
| Event | Effect |
|---|---|
cartpops:open |
Opens the drawer. If it is already open, it refreshes the cart data. |
cartpops:close |
Closes the drawer. |
cartpops:toggle |
Opens the drawer if it is closed, and closes it if it is open. |
The drawer listens from the moment its script module has run. The module loads after the page’s classic scripts, so an event dispatched during page load, before the module runs, is lost. Dispatch from a click or other user action, or wait for DOMContentLoaded. The events do nothing if CartPops is switched off or the drawer is not on the page.
When the drawer opens, it reads the cart again, unless the cart data was refreshed in the last ten seconds.
Example: open the drawer from your own button
<button type="button" id="my-cart-button">Cart</button>
document.addEventListener( 'click', ( event ) => {
const button = event.target.closest( '#my-cart-button' );
if ( ! button ) {
return;
}
event.preventDefault();
document.dispatchEvent( new CustomEvent( 'cartpops:open' ) );
} );
The listener is on document, so it also works for buttons that your theme adds later. When the drawer closes, focus returns to the element that was focused when it opened, which is your button here.
Event you can listen to
cartpops:count-updated
CartPops dispatches this on document after the cart item count changes. The count is the total quantity of all cart lines, as an integer.
document.addEventListener( 'cartpops:count-updated', ( event ) => {
console.log( event.detail.count ); // For example 3.
} );
| Property | Type | Description |
|---|---|---|
event.detail.count |
number |
Total quantity in the cart after the change. |
Things to know:
- Removing a line fires the event straight away. Changing a quantity with the plus and minus buttons fires it after CartPops has confirmed the change with the server, which is a fraction of a second later.
- It can fire more than once with the same value. Do your own check if that matters.
- It does not fire at page load unless CartPops has to read the cart because the page may be out of date, for example on a cached page. Take the first value from your own markup or from the WooCommerce
woocommerce_items_in_cartcookie.
Example: keep a header counter in sync
document.addEventListener( 'cartpops:count-updated', ( event ) => {
const count = Number( event.detail?.count ?? 0 );
document.querySelectorAll( '[data-header-cart-count]' ).forEach( ( element ) => {
element.textContent = String( count );
element.hidden = count === 0;
} );
} );
Give your counter element the attribute data-header-cart-count (or any selector you prefer). CartPops uses the same event to update the Blocksy header badge and its own Pro shipping meter.
WooCommerce events CartPops listens to
CartPops keeps itself in step with the rest of the store by listening to these events. You do not need to dispatch them, but you can use them to tell CartPops that the cart changed.
| Event | Source | What CartPops does |
|---|---|---|
added_to_cart |
jQuery, on document.body. Arguments: fragments, cart hash, button. |
Reads the CartPops cart state from the .cartpops-cart-json fragment, so it needs no extra request. If the fragment is missing it reads the cart. Opens the drawer if Open drawer on is Add to cart and the button does not opt out. |
removed_from_cart |
jQuery, on document.body. |
Updates the cart without opening the drawer. |
updated_wc_div |
jQuery, on document.body. |
Reads the cart again. |
wc_fragments_refreshed |
jQuery, on document.body. |
Reads the cart again. |
wc-blocks_added_to_cart |
DOM event on document.body, from WooCommerce blocks. |
Reads the cart from the WooCommerce cart store. Opens the drawer if Open drawer on is Add to cart. |
wc-blocks_removed_from_cart |
DOM event on document.body. |
Updates the cart without opening the drawer. |
wc/store/cart |
A subscription to the WooCommerce wp.data store. |
Applies cart changes that WooCommerce blocks make, such as quantity, coupon or shipping changes. Does not open the drawer. |
CartPops also takes over clicks on the WooCommerce Mini-Cart block button when Integration mode under WooCommerce Mini Cart (Advanced > General) is set to Replace.
On a single product page, Add to cart on product pages without reloading (Advanced > General) makes CartPops submit the classic form.cart in the background. It listens for submit on window, so your handlers on the form or document run first. If one calls event.preventDefault(), CartPops leaves the form alone. After a confirmed add it fires added_to_cart with refreshed fragments and the clicked button, so the per-button opt-out below works on the product page too.
jQuery must load first
CartPops attaches the jQuery events (added_to_cart, removed_from_cart, updated_wc_div and wc_fragments_refreshed) only if jQuery already exists when its script runs. If a speed plugin delays or defers jQuery, CartPops never hears these events. The wc-blocks_* events are plain DOM events and do not need jQuery.
Stop one button from opening the drawer
Add data-cpops-cart-open="false" to an AJAX add to cart button to add the product without opening the drawer.
<a href="?add-to-cart=123" data-product_id="123" data-cpops-cart-open="false" class="button add_to_cart_button ajax_add_to_cart">
Add to cart
</a>
This works for classic AJAX adds, where WooCommerce fires added_to_cart with the button. It does not apply to adds made by WooCommerce blocks. To stop opening on every add, set Open drawer on to Launcher click only, or use the cartpops_add_to_cart_trigger filter.
Example: open the drawer after your own AJAX add
If your own code adds a product with WooCommerce’s AJAX add to cart request, trigger the standard added_to_cart event with the response. CartPops then updates from the response and opens the drawer, following the Open drawer on setting.
// `data` is the JSON response from WooCommerce's add_to_cart AJAX request.
function announceAddedToCart( data, button ) {
window.jQuery( document.body ).trigger( 'added_to_cart', [
data.fragments,
data.cart_hash,
window.jQuery( button ),
] );
}
If you add to the cart some other way and only want the drawer to show, dispatch cartpops:open. If you changed the cart less than ten seconds after the drawer last refreshed its data, the drawer can briefly show the earlier state.
What CartPops dispatches for WooCommerce
After CartPops changes the cart itself, for example a quantity change, a coupon, or a recommendation add, it asks WooCommerce to refresh the other cart widgets. It does this once, about 50 milliseconds after the last change:
- It triggers the jQuery
wc_fragment_refreshevent ondocument.body, if jQuery is present. - It asks the WooCommerce
wc/store/cartstore to load the cart again.
CartPops does not listen to wc_fragment_refresh itself.
CartPops does not fire added_to_cart, removed_from_cart or adding_to_cart for the adds and removals it makes, such as a recommendation add. Analytics plugins that rely on these events will not see those actions.
Not public
These exist in the code but are internal, and can change without notice: the cartpops Interactivity store and its actions, the global keys Symbol.for('cartpops.cartDrawerEventBridge') and Symbol.for('cartpops.wooCartSurfaceSync'), and the window.wp.interactivity global, which WordPress does not guarantee.
The drawer’s DOM does show its state: while it is open, .cpops-drawer has the class cpops-drawer-open. You can watch that class if you really need to know, but this is rendered markup, not a promised API, and CartPops sends no event when it changes.