# WooCommerce + ForgeCache — Cart, Mini-Cart, and Checkout Issues

> WooCommerce cart empty after add-to-cart, mini-cart not updating, or stale checkout with ForgeCache: what it excludes automatically and how to fix each.

- Canonical: <https://royalplugins.com/support/forgecache/woocommerce-caching-issues/>
- Last updated: 2026-06-01
- HTML version: <https://royalplugins.com/support/forgecache/woocommerce-caching-issues/>

---

WooCommerce stores have three states (anonymous browsing, anonymous-with-cart, logged-in customer) that ForgeCache caches very differently. When something feels off — a cart appearing empty after add-to-cart, the mini-cart not updating in the header on a shop archive, a stale checkout page, or the rare cross-customer leak — this doc maps each symptom to what ForgeCache is actually doing and how to fix it.

Before chasing a fix — confirm WooCommerce optimization is enabled

Most of the safety behavior below depends on the **WooCommerce** toggle in **ForgeCache → Settings → Advanced**. If that toggle is off, ForgeCache still respects WooCommerce cart cookies and won’t cache logged-in users, but it won’t apply the shop-archive mini-cart-fragments optimization and won’t actively detect WC pages. Open WP Admin → ForgeCache → Settings → Advanced and make sure **Enable WooCommerce optimizations** is ticked before working through this article.

### What ForgeCache Already Does for WooCommerce

Even with zero configuration, ForgeCache **never** page-caches:

- The **cart, checkout, and My Account pages** (detected via `is_cart()`, `is_checkout()`, `is_account_page()`)
- Any request from a **visitor with a WooCommerce cart cookie set** (`woocommerce_items_in_cart`, `woocommerce_cart_hash`, or `wp_woocommerce_session_*`)
- Any **logged-in user** — customer accounts, admin sessions, store managers, all bypass page cache
- Any **POST request** (so checkout submissions, login forms, add-to-cart forms never hit cache)
- **admin-ajax.php**, the REST API, and WP-CLI / cron operations

If you’re seeing a WooCommerce caching issue, it’s almost always one of: the WooCommerce toggle is off, an additional cache layer above ForgeCache is the culprit, or you’re hitting the intentional mini-cart-fragments optimization on shop archives (issue 2 below).

## Issue 1 — Cart Page Shows Empty After Adding Products

Customer adds a product to cart, navigates to the cart page, and sees “Your cart is currently empty” — but the product is actually there (other carts, server-side cart API, etc. confirm).

### What this almost certainly is

A cache layer *above* ForgeCache (managed-host edge cache, CDN page cache, reverse proxy) is serving a stale cart page that was captured during a previous anonymous visit. ForgeCache itself never caches the cart page — the exclusion is hardcoded.

### How to verify

#### Open an incognito window, add a product, go to cart

Does the cart show the item? If yes, ForgeCache is fine — the issue is browser- or cookie-side. If the cart is empty even in incognito (with an item just added in that same incognito session), continue.

#### Check response headers on the cart page

DevTools → Network → reload `/cart/` → check the response headers for:

- `cf-cache-status: HIT` — Cloudflare is serving from edge cache. **Bad — cart shouldn’t be cached.**
- `x-served-by: cache-XXX` + `age: NN` with NN > 0 — a CDN or reverse proxy is serving stale.
- `x-forgecache: HIT` in DevTools but you have the toggle enabled — that’s a bug, contact support.

### The fix

Configure the *upstream* cache layer to exclude WooCommerce pages and cookies. The exact steps depend on the layer:

- **Cloudflare** — add a Cache Rule that bypasses cache for paths matching `/cart/*`, `/checkout/*`, `/my-account/*`, and any request that includes a `woocommerce_*` cookie. Cloudflare’s **Caching → Cache Rules** panel; create a rule with eligibility set to **Bypass cache**.
- **Cloudflare APO** — APO has WooCommerce auto-detection that’s supposed to bypass cache for WC cookies. If you’re still seeing stale carts with APO enabled, the auto-detection may have missed your WC install — check the APO settings panel in your Cloudflare dashboard (its location has moved across Cloudflare redesigns), or escalate to Cloudflare support.
- **Managed-host edge cache** (Kinsta, WP Engine, Pressable, SiteGround SuperCacher, etc.) — every reputable WC host auto-excludes cart/checkout/account. If they’re not, that’s a host support ticket.
- **nginx / Varnish / LiteSpeed** — if you control the reverse proxy, add a bypass for any request with the `woocommerce_items_in_cart` or `wp_woocommerce_session_*` cookie set.

## Issue 2 — Mini-Cart in the Header Doesn’t Update After Add-to-Cart (Shop / Category Pages)

Customer is on the shop page or a category archive, clicks **Add to cart** on a product card, and the mini-cart count in the header stays at zero (or whatever it was before). The cart page itself *does* have the item, but the header doesn’t update without a full page reload.

This is intentional behavior of the WooCommerce optimization toggle

When **WooCommerce optimizations** is enabled, ForgeCache dequeues the `wc-cart-fragments` script on three page types: `is_shop()`, `is_product_category()`, and `is_product_tag()`. `wc-cart-fragments` is WooCommerce’s AJAX-based mini-cart updater — it runs on *every* page load to ask the server “what’s in this visitor’s cart right now?” That AJAX call hits `admin-ajax.php` on every page, which is one of the most-cited performance bottlenecks on busy WooCommerce stores. ForgeCache disables it specifically on shop archives because the trade-off is usually worth it: faster shop browsing in exchange for mini-cart that updates only after page reload.

### Three ways to handle it

#### Option A — Accept the trade-off (recommended for most stores)

The mini-cart still updates correctly on single product pages, the cart page, the checkout page, and every other non-archive page. The only place it doesn’t live-update is on shop / category / tag listings, and the customer gets the correct cart count as soon as they navigate anywhere else. For most stores this is the right call.

#### Option B — Disable WooCommerce optimizations entirely

If live mini-cart updates on shop archives are critical to your store (e.g. high-velocity add-to-cart UX with a side-cart pattern), the simplest fix is to turn off the WooCommerce toggle. **WP Admin → ForgeCache → Settings → Advanced → WooCommerce** → uncheck **Enable WooCommerce optimizations** → Save Changes. ForgeCache will still respect WC cart cookies and exclude cart/checkout/account from page cache, but it’ll stop dequeuing the mini-cart fragments script. Your shop pages will be marginally slower but the mini-cart will update live everywhere.

#### Option C — Selectively re-enable fragments on archives via a tiny mu-plugin

If you want most of the WC optimizations but not the fragments dequeue, drop this into `wp-content/mu-plugins/forgecache-keep-fragments.php` (create the `mu-plugins` directory if it doesn’t exist):

```
<?php
// Keep wc-cart-fragments enabled on shop archives despite ForgeCache's
// WooCommerce optimization. Trade speed for live mini-cart updates.
add_action( 'init', function() {
    if ( class_exists( 'ForgeCache_WooCommerce' ) ) {
        $inst = ForgeCache_WooCommerce::instance();
        remove_action( 'woocommerce_before_shop_loop', array( $inst, 'disable_cart_fragments_on_shop' ) );
    }
}, 20 );
```

This unhooks just the fragments dequeue while leaving every other WC optimization (generator tag removal, checkout password-strength-meter dequeue) intact.

## Issue 3 — Checkout Page Shows Stale Data (Shipping Methods, Totals, Form State)

Customer reaches checkout but sees stale shipping rates, an old cart total, or form fields pre-filled with a previous customer’s info.

### What this almost certainly is

Same root cause as issue 1 — an upstream cache layer is serving a captured-once-and-reused checkout page. ForgeCache hardcodes `is_checkout()` to never page-cache. POST requests (the checkout submission) bypass cache by definition.

### How to verify

Open an incognito window, add a product, go to checkout. Are the totals correct? If yes, the issue is in your customer’s browser/cookies. If no — or if you see another visitor’s form prefill data — check the response headers on `/checkout/` the same way as issue 1.

### The fix

Same as issue 1: exclude `/checkout/*` and the WC cookie set at every cache layer above WordPress. If it’s Cloudflare, a Cache Rule with **Bypass cache** for the checkout path is the cleanest fix. If you’re running Cloudflare APO with WooCommerce auto-detected, APO should be excluding checkout automatically — if it isn’t, Cloudflare support can verify whether APO detected your WC install correctly.

Don’t add “exclude /checkout/” to ForgeCache’s URL exclusion list and call it fixed

ForgeCache already excludes checkout via the dedicated `is_checkout()` predicate. If you’re seeing stale data, adding the URL to ForgeCache’s exclusion list won’t change anything — you’d be telling ForgeCache to do what it already does. The bypass needs to happen at the upstream layer (CDN, host edge cache) that’s actually serving the stale response.

## Issue 4 — Customer A Sees Customer B’s Cart / Account Data (Critical)

The rare and serious one. Customer A reports seeing items they didn’t add, or a wrong email/shipping address pre-filled on checkout, or another customer’s order data in My Account.

Treat this as a P0 — rotate sessions and investigate immediately

If a customer reports seeing someone else’s data, two things to do *before* debugging cache layers: (1) ask the customer to log out and log back in, and clear cookies if they’re willing — this gives them their own clean session. (2) Note the time the leak was observed; you’ll need it for the cache audit below. If you have GDPR / PCI compliance obligations, treat this as a potential data-disclosure incident and follow your normal IR process.

### What this almost certainly is

A cache layer above ForgeCache is serving an HTML response that includes server-side session data (cart contents, checkout pre-fill, account info) to multiple visitors. The classic cause is a CDN or reverse proxy caching responses without honoring the cookies that identify the customer.

### How to verify

#### Confirm it’s not ForgeCache

ForgeCache will not cache any request from a logged-in user (`is_user_logged_in()` short-circuits the cache decision) and will not cache any request with a WooCommerce session cookie. If a logged-in customer is seeing another customer’s data, the response did not come from ForgeCache’s cache — it came from somewhere else.

#### Check the response Vary / Set-Cookie / Cache-Control headers

On the affected page (replicate by logging in as a test customer), DevTools → Network → check the response headers. A correctly configured WC page should return `Cache-Control: no-store` or `private` on logged-in / cart-bearing requests, and the upstream cache should be respecting that.

#### Identify the layer that captured the leaked response

Look for any cache-status header that isn’t `x-forgecache`:

- `cf-cache-status: HIT` on a logged-in / cart page — Cloudflare is the source of the leak.
- `x-served-by` + `age: NN` — a managed-host edge cache or upstream CDN.
- `x-litespeed-cache: hit` — LiteSpeed Cache plugin (running in addition to ForgeCache, which is unsupported).

### The fix

Disable or correctly configure whichever cache layer is the source. Concretely:

- If **Cloudflare is HIT’ing logged-in pages**, your Cache Rules / Page Rules are too aggressive. Add a rule that bypasses cache for any request with the `wordpress_logged_in_*`, `wp-postpass_*`, or any `woocommerce_*` cookie set. Cloudflare APO with WC detection does this automatically — if APO is enabled but you’re still seeing this, escalate to CF support.
- If **a host edge cache** is the culprit, open a host support ticket immediately — this is a misconfiguration on their side and they should have a per-customer fix.
- If **another caching plugin is running alongside ForgeCache** (LiteSpeed Cache, W3 Total Cache, WP Super Cache), deactivate it. Running two page-cache plugins simultaneously is unsupported and a common source of data-leak bugs.

After applying the fix, force-purge every cache layer (ForgeCache → Clear All Cache, Cloudflare → Purge Everything, host edge cache → full purge) before testing again. Stale entries from before the fix will continue serving the leak until they roll over naturally.

## Other Common WooCommerce + Caching Symptoms

### Add-to-Cart button does nothing / page reloads to homepage

Usually an AJAX failure rather than a caching issue. ForgeCache excludes every request where `wp_doing_ajax()` is true — which covers `admin-ajax.php` (the route most `wc-ajax` calls take) — so this is rarely a ForgeCache layer problem. Common actual causes: a security plugin blocking the AJAX request, an upstream CDN caching the `wc-ajax` endpoint, or a JS error preventing the AJAX call. Open DevTools → Network and look at the `?wc-ajax=add_to_cart` request when you click the button. Anything other than `200` with a JSON response is a clue.

### Currency switcher / multi-currency plugins showing wrong prices

Multi-currency plugins typically store the visitor’s chosen currency in a cookie. If that cookie name isn’t in ForgeCache’s dynamic-cookie watchlist, anonymous visitors might see a cached page in the wrong currency. The watchlist is hardcoded to standard WC + EDD cookies; if your currency plugin uses a custom cookie name, the simplest fix is to disable page caching on currency-switched visits via the `forgecache_should_cache_page` filter:

```
<?php
add_filter( 'forgecache_should_cache_page', function( $should_cache ) {
    // Replace with your currency plugin's actual cookie name
    if ( isset( $_COOKIE['my_currency_cookie'] ) ) {
        return false;
    }
    return $should_cache;
} );
```

### Product price update doesn’t appear on shop archive

ForgeCache invalidates the cache for a specific post URL plus the homepage on `save_post`. It doesn’t automatically purge the shop archive page on a product price change — the archive page’s cache will roll over naturally on its TTL (default 1 hour) or you can force it manually via **ForgeCache → Clear All Cache**. If you change prices frequently and want shop archives to update faster, lower the cache TTL in **Settings → Cache → Cache Expiration**.

### Checkout content area blank with WooCommerce Blocks + Blocksy / Stackable / block-based builders

If you’re running the WooCommerce Cart Block or Checkout Block (or any block-based builder that server-renders React components — Blocksy, Stackable, similar), and the entire checkout content area went blank after enabling **Core Web Vitals**, the cause is the CWV image-dimensions transformer mutating `<img>` attributes after server-side rendering. React hydrates on the client, finds attributes it didn’t generate, treats the SSR output as a mismatch, and unmounts the affected component.

**Fixed in ForgeCache 2.1.19+** — the CWV transformer now auto-skips on cart, checkout, and account pages. If you’re still on 2.1.18 or earlier, update from **WP Admin → Plugins**, or as a temporary workaround disable the **Core Web Vitals** toggle in **Settings → Advanced**.

CSS optimization + JS delay + block-based builders — test carefully

Block-based theme/builder stacks (Blocksy + Blocksy Companion Pro, Stackable Premium, Gutenberg block themes like Twenty Twenty-Four with custom Block patterns, etc.) tend to be more sensitive to post-buffer transformations than classic PHP-templated themes. Combining **CSS Optimization** + **Delay JavaScript until user interaction** on the same site can occasionally produce rendering issues on pages with heavily-nested Gutenberg blocks — missing styles below the fold, delayed interactivity on accordion / tab / slider blocks, or hydration mismatches on third-party block libraries. The fixes for 2.1.19 (CWV skip on WC dynamic pages) address the highest-volume case, but if you hit other rendering issues on block-heavy templates: enable optimizations one at a time, test each public page type (homepage, single post, product, shop archive, cart, checkout) after each change, and use the [Page Optimizer](https://royalplugins.com/support/forgecache/page-optimizer/) to surgically defer/delay individual scripts rather than relying on the global toggles.

## Still Stuck? Email Priority Support

If you’ve worked through the relevant issue above and the symptom persists:

Email **[support@royalplugins.com](mailto:support@royalplugins.com)** with the diagnostic info below. Priority email support is included with your ForgeCache Pro license — typical response time is within 24 hours, and we treat suspected cross-customer data leaks (issue 4) as highest priority.

#### Information to include in your email

- Your **ForgeCache version** + **WooCommerce version** + **WordPress version** + **hosting provider**.
- **Which issue (1, 2, 3, or 4)** from this doc you’re hitting.
- The **response headers** from the affected page (DevTools → Network → Response Headers, screenshot or copy/paste).
- Whether **ForgeCache’s WooCommerce optimization toggle** is enabled.
- Whether **any other caching plugin** is also active (LiteSpeed Cache, W3 Total Cache, WP Super Cache, WP Rocket, etc. — running two page-cache plugins is unsupported).
- Whether you’re running **Cloudflare APO** or a managed-host edge cache, and whether the issue reproduces with that layer’s cache cleared.
- For issue 4 specifically — the **approximate time the leak was observed** and the **steps to reproduce**. Do NOT include any leaked customer PII in the email.

Related ForgeCache docs

- [**Connecting Cloudflare to ForgeCache**](https://royalplugins.com/support/forgecache/connecting-cloudflare/) — if Cloudflare is the upstream cache layer involved in any of the issues above, the auto-purge integration helps keep CF and ForgeCache in sync.
- [**Cloudflare connection fails — “Invalid API token”**](https://royalplugins.com/support/forgecache/cloudflare-invalid-api-token/) — if you’re trying to wire up Cloudflare auto-purge and the token is being rejected.
- [ForgeCache Documentation](https://royalplugins.com/support/forgecache/) — back to the main support page.
