NextWoo
Speed fixes

Disable WooCommerce cart fragments without breaking the header cart

The wc-cart-fragments script keeps a cached header cart honest and pays with an uncacheable request when a visit starts. Check whether your store still makes it, then remove it where nobody sees a cart.

Since WooCommerce 7.8, released in June 2023, the cart fragments script loads only on pages that render the classic Cart widget, so on many stores there is nothing left to disable. Check before you write code. Open a page in a private window, filter the DevTools Network tab for get_refreshed_fragments and reload. No POST request means no problem. If one appears, your theme still renders the widget, as Storefront does in its header. Dequeue the script on templates that show no cart, keep it wherever a page-cached header displays a cart count, and expect a theme like WoodMart to need its header cart removed before fragments can go.

01

What a get_refreshed_fragments request costs, and when it fires

The cart fragments script, registered as `wc-cart-fragments`, sends a POST to `/?wc-ajax=get_refreshed_fragments`. That is WooCommerce's own AJAX endpoint, not admin-ajax.php. To answer it, WordPress and WooCommerce boot in full, load the shopper's session and render the mini-cart template. The reply is JSON. It holds HTML snippets keyed by CSS selector plus a cart hash, and it carries no-cache headers, so neither a page cache nor a CDN can absorb it. It does not fire on every page view, which is the claim repeated most often about it. The script keeps the fragments in the browser's sessionStorage and skips the request while the stored hash matches the `woocommerce_cart_hash` cookie. It asks the server again on a visit's first page in a tab, 24 hours after the fragments were stored, when another tab changes the cart, when the browser restores a page from its back-forward cache, and on every page if the browser blocks storage. Each attempt times out after 5,000 ms. So the cost lands on the landing page. On a store served from a full-page cache, that POST can be the only part of the view that runs PHP, and it scales with sessions. In a scenario where an email blast starts 10,000 sessions in an hour, PHP answers 10,000 of these requests, however well the homepage is cached.

02

WooCommerce 7.8 moved the script into the Cart widget

Pull request #35530, shipped in WooCommerce 7.8.0 on June 13, 2023, removed the site-wide enqueue. Since then `WC_Widget_Cart::widget()` enqueues the script while it renders, and the widget skips the cart and checkout pages through the `woocommerce_widget_cart_is_hidden` filter, so the script stays off those two as well. A store with no classic Cart widget anywhere stopped making the request the day it updated. Themes that print the widget in their own header kept it on every page. Storefront, WooCommerce's own theme, calls `the_widget( 'WC_Widget_Cart' )` inside its header cart, and the WooCommerce team's announcement names hard-coded widgets as the case to watch. Most dequeue guides predate mid-2023. On a version older than 7.8 the script really does load everywhere, and an update removes it from more pages than any snippet would.

03

Seeing the request in Chrome DevTools

Use a private window. A tab that has already loaded the site holds fragments in sessionStorage and will hide the very request you are looking for. Open DevTools, go to the Network tab, type `wc-ajax` in the filter box and load the homepage: a POST to `?wc-ajax=get_refreshed_fragments` means the script ran. Filter for `cart-fragments` and the file itself shows up. Repeat on a blog post, a category and a product page, since themes differ by template. To learn what enqueued it, open the Scripts panel in Query Monitor, which lists each handle with its dependencies; this one needs `jquery` and `wc-js-cookie`. If this request turns out to be a small part of the weight, the plugin audit ranks the rest.

04

A conditional dequeue, hooked late enough to stick

The fix is one call, `wp_dequeue_script( 'wc-cart-fragments' )`, wrapped in a condition that names the pages where nobody needs a live cart: `is_front_page()`, `is_singular( 'post' )`, a landing page built for ads. It belongs in a child theme's functions.php or a must-use plugin, never the parent theme, where the next update deletes it. Timing is where copied snippets fail. The common version hooks `wp_enqueue_scripts` at priority 99, which worked while WooCommerce enqueued the script during that hook. Not anymore. Since 7.8 the Cart widget enqueues it later, as the header renders, and the earlier dequeue is undone. Hook the same function to `wp_footer` below priority 20, where WordPress prints late-enqueued scripts, and keep the `wp_enqueue_scripts` hook for themes that enqueue the script themselves. Two shortcuts are worse. A site-wide dequeue on a theme with a header cart trades the request for a wrong count on every cached page. A condition such as `WC()->cart->is_empty()` looks smarter and fails under page caching: PHP evaluates it once, when the cache fills, and every later visitor gets that first visitor's answer. Where a page needs no cart dropdown, returning true from `woocommerce_widget_cart_is_hidden` removes the widget and its script together.

05

What stops updating once the script is gone

The header cart count and the mini-cart drawer stop correcting themselves on page load. Adding to cart keeps working, since an AJAX add-to-cart button gets fragments back in its own response and updates the header on that page. The trouble starts on the next click. If that page comes out of the page cache, its header shows the count baked into the cached copy, which is zero when an anonymous visitor filled it, while the cart holds two items. Pages the cache skips, such as cart and checkout, render the right number on the server. This is where cache plugins stop helping: the cache creates the stale count. WoodMart is the clearest named limit. Its header cart depends on fragments, and when a store owner asked in February 2024 how to switch them off, WoodMart support replied that the feature is "required to make the shopping cart widget work correctly" and that the way to disable it is to remove the shopping cart widget from the header. Expect the same from any theme whose header cart is a WooCommerce widget, Storefront included.

06

Writing to woocommerce_add_to_cart_fragments from a theme

Developers who need their own header element kept current add it through the `woocommerce_add_to_cart_fragments` filter. It receives an array keyed by CSS selector, with `div.widget_shopping_cart_content` as WooCommerce's default entry, and the same array goes out in three responses: the fragments refresh, AJAX add to cart and AJAX remove from cart. Storefront registers `a.cart-contents` and `a.footer-cart-contents` this way. The JavaScript swaps each match with jQuery's replaceWith, so the returned HTML must include the outer element carrying the same selector. Return only the inner count and the first update works, then the second finds nothing to replace. Keep the callbacks cheap: they run on each of those requests, and a fragment that renders thumbnails and prices costs more than one that returns a number.

07

A lighter design starts from a cookie WooCommerce already sets. `woocommerce_items_in_cart` exists only while the cart has items, its value is 1 rather than a count, and JavaScript can read it because WooCommerce sets its cookies without the HttpOnly flag by default. A small script can skip the network for every visitor who has not added anything yet. For those, `GET /wp-json/wc/store/v1/cart` returns `items_count`. Keep the result in localStorage beside the `woocommerce_cart_hash` value and fetch again only when the hash changes. The Mini-Cart block, which WooCommerce recommends to theme developers, does not use the fragments API, but it is not request-free: in the current source its script requests `/wc/store/v1/cart` with `cache: 'no-store'` as it loads. If the goal is fewer uncached requests, the block moves the cost rather than removing it, and the cookie gate is the better choice; if the goal is to stop maintaining custom cart code, the block wins. A headless storefront reads the same Store API and settles this once, one of the trade-offs WooCommerce speed work weighs.

08

Where the free store audit looks for this request

Our free store audit runs the private-window check above on your landing templates, names the theme or plugin that enqueues `wc-cart-fragments`, and checks whether your page cache serves a header cart that would go stale without it. It reports and changes nothing. The Care Plan, from $150/mo, keeps a dequeue rule like this one working through theme and WooCommerce updates. Prices are on pricing.

Frequently asked questions

Still have questions?

Reach out and we'll get back to you within 24 hours.

Contact us
How do I disable cart fragments on the homepage only?

Dequeue wc-cart-fragments inside an is_front_page() check, hooked to wp_footer below priority 20 and to wp_enqueue_scripts. Skip it if the cached homepage header shows a cart count.

Does WooCommerce still load cart fragments on every page?

No, not since 7.8.0 in June 2023: only where the classic Cart widget renders. Themes that hard-code that widget in the header, Storefront among them, still load it site-wide.

What is the woocommerce_add_to_cart_fragments filter?

A filter for adding your own HTML to the fragments WooCommerce returns after a refresh, an AJAX add to cart or a removal. Keys are CSS selectors, and each value replaces the matching element whole.

How do I refresh cart fragments after a custom add to cart?

Trigger the event on the body: jQuery( document.body ).trigger( 'wc_fragment_refresh' ). The script then fetches fresh fragments. It works only on pages where wc-cart-fragments is loaded.

Will disabling cart fragments break my cart?

No. Cart contents live in the WooCommerce session, not in the script. The header count and mini-cart drawer on page-cached pages are what go wrong.

Terms used on this page
Related reading
  • WooCommerce plugin bloat

    Which WooCommerce plugins slow your store: cart fragments, filters, review and chat widgets, sliders. How to measure each on staging and what to remove first.

  • WooCommerce speed optimization

    WooCommerce speed optimization service: a free audit, a week of measured fixes on your current theme, and a frontend rebuild only if the theme is the ceiling.

  • WooCommerce cart API

    Build a responsive cart on a Next.js storefront with the WooCommerce Store API: session tokens, coupons and stock validation, then a safe handoff to checkout.

See how many sales your store is losing

Start with a free speed audit. You'll get your store's real numbers and an honest recommendation — even if it's "you don't need us".

Anything you already suspect — checkout feels slow on phones, the category pages crawl, you were told the theme is the problem. Guesses are useful; we check them.

No sales call — you'll get a written report with your store's numbers.

By requesting an audit you accept our Privacy policy and Terms of service. We may publish an anonymised summary of the findings as an example of our work. We never name your business without your written consent.