WooCommerce Add to Cart AJAX Not Working: Real Fix

WooCommerce Add to Cart AJAX button spinning forever or not responding? Fix broken cart fragments, jQuery conflicts, and the page cache rules with code.
WooCommerceWordPressAJAX
April 23, 20265 min read927 words

The Problem

A client pinged me on Monday: the Add to Cart button on their WooCommerce shop page had stopped working. Click it on a simple product and the spinner starts, but the cart count never updates and no "View cart" link appears. Refresh the page and the product is in the cart, so the database write is fine. The AJAX layer is broken.

If you are seeing the same thing (spinner hangs, cart icon stays at zero, no "added to cart" notice), the cause is almost always one of four things: cart fragments fetching too often, a 403 from page cache, a jQuery conflict from a recently updated plugin, or the site running behind full-page cache with no fragment bypass.

Why It Happens

WooCommerce ships an AJAX endpoint at /?wc-ajax=add_to_cart and another at /?wc-ajax=get_refreshed_fragments. The second one pulls the updated mini-cart HTML and injects it into every page. It runs on every page load by default. Two things go wrong on live stores.

First, most page cache plugins (WP Rocket, W3 Total Cache, LiteSpeed Cache) cache the AJAX response along with the page. A logged-out visitor hits a cached page, the cached response contains another user's fragment, and the fragment hash mismatches. The cart UI gives up silently.

Second, wc-ajax requests are POST to the current page URL with a query string. Cloudflare "Cache Everything" page rules, and some host-level caches (Kinsta, WP Engine, SiteGround), will 200-cache or 403-block these POST calls if you have not excluded them.

Third (this is the one I hit last week), a plugin update shipped a newer jQuery and broke WooCommerce's woocommerce_add_to_cart_params localization. The add-to-cart button class ajax_add_to_cart needs that params object, and if it is missing, clicking the button just fires the form submit and falls back to a full page reload.

The Fix

Step 1: Check the browser console first. Open DevTools, click Add to Cart, watch the Network tab.

  • If you see a 403 on /?wc-ajax=add_to_cart, your cache or firewall is blocking POSTs.
  • If the call returns 200 but the response body is HTML of your homepage, your page cache is serving the wrong content.
  • If there is no network call at all, the jQuery handler is not bound. Open the Console tab and look for a woocommerce_params is not defined error.

Step 2: Exclude wc-ajax from page cache. For most hosts the fastest fix is adding this to wp-config.php above the ABSPATH line so cache plugins see it:

if ( isset( $_GET['wc-ajax'] ) ) {
    define( 'DONOTCACHEPAGE', true );
    define( 'DONOTCACHEOBJECT', true );
    define( 'DONOTCACHEDB', true );
}

If you are on Cloudflare with a "Cache Everything" page rule, add a bypass:

URL matches: example.com/*wc-ajax=*
Cache Level: Bypass

Do the same for /cart/, /checkout/, and /my-account/ if you have not already. These three should never hit page cache.

Step 3: Force cart fragments to refresh properly. If the mini cart still does not update after Step 2, the fragment hash is stuck in sessionStorage. Add this snippet to your theme's functions.php to clear it on every add-to-cart:

add_action( 'wp_footer', function () {
    if ( ! function_exists( 'is_woocommerce' ) ) {
        return;
    }
    ?>
    <script>
    jQuery( function ( $ ) {
        $( document.body ).on( 'added_to_cart', function () {
            sessionStorage.removeItem( 'wc_fragments_' + wc_cart_fragments_params.ajax_url.split( '?' )[0] );
            sessionStorage.removeItem( 'wc_cart_hash_' + wc_cart_fragments_params.ajax_url.split( '?' )[0] );
        } );
    } );
    </script>
    <?php
}, 99 );

This forces the mini cart HTML to re-fetch from the server after any add-to-cart event, instead of trusting a potentially stale sessionStorage value.

Step 4: Re-enable AJAX add-to-cart in WooCommerce settings. Go to WooCommerce → Settings → Products → General and confirm both boxes are checked:

  • Enable AJAX add to cart buttons on archives
  • Redirect to the cart page after successful addition (leave this OFF if you want the spinner flow)

If a plugin toggled these off during an update (happens more than you would think), the button will just act like a regular link.

Step 5: Rule out the jQuery conflict. If the console shows wc_add_to_cart_params is not defined, a plugin is dequeuing wc-add-to-cart or loading jQuery in defer/async mode before WooCommerce's inline script runs. Check the HTML source and confirm wc-add-to-cart-js-extra is present. If it is not, find the plugin that is stripping WooCommerce scripts. The usual culprits are Autoptimize aggressive JS settings and Perfmatters "Delay JavaScript" with an overly wide pattern. Exclude wc-add-to-cart and woocommerce from delay rules.

The WooCommerce AJAX API docs cover the request/response contract if you need to debug further.

The Lesson

Cart AJAX feels like a plugin issue but it is almost always a cache or script-aggregation issue. Check the Network tab first, exclude wc-ajax everywhere that caches, and never let page cache or JS delay rules touch WooCommerce's inline params.

If your store is losing sales to a broken cart right now, I fix this kind of thing fast — see my services, or if you are dealing with a related checkout issue I wrote up the WooCommerce Checkout Block payment methods fix last week.

Back to blogStart a project