LiteSpeed LSCache + OpenCart (Journal3): Mini cart shows wrong item count on cached pages (random / 0 items)

#1
Hi all,

I’m running OpenCart 3.x with the Journal3 theme on LiteSpeed Web Server (LSWS) with LSCache enabled. I’m trying to properly cache public pages (home, category, product pages) while keeping the mini cart (header cart) dynamic per user.

Problem:
When LSCache is enabled, the mini cart shows incorrect values on cached pages:
  • Sometimes it shows 0 items
  • Sometimes it shows 1 or 3 items randomly
  • On the first visit to a page it may show the correct value, but when navigating back to the homepage (which is cached), the mini cart shows old/wrong values
  • This causes inconsistent cart behavior and even prevents cart updates from reflecting correctly on cached pages

Current setup:
  • LiteSpeed Web Server Enterprise
  • LSCache enabled (public cache for HTML pages)
  • Private cache enabled
  • OpenCart 3.x
  • Journal3 theme
  • LSCache OpenCart extension enabled
  • ESI Modules configured, e.g.:
    • common/cart → ESI with private cache
    • common/cart/info → ESI with private cache
    • journal3/cart → ESI with private cache
  • Cart/checkout/account pages are excluded from cache via .htaccess and LSCache settings

Symptoms / Findings:
  • Cached pages (x-litespeed-cache: hit) show outdated cart data in the header
  • The mini cart fragment sometimes appears to be cached as part of the full page
  • In some cases admin messages (like “Success: You have modified LiteSpeed Cache extension”) appeared on frontend cart pages, indicating private/admin content leaking into public cache
  • Disabling LSCache fixes the problem immediately

What I suspect:
  • The mini cart fragment is not being consistently served as ESI private cache
  • Possibly the Journal3 mini cart endpoint is different from the default common/cart route
  • Or LSCache is not correctly separating public cache and private cache for cart fragments

Question:
What is the correct and recommended setup for:
  • LSCache + OpenCart
  • Journal3 mini cart
  • ESI (Edge Side Includes) for cart fragments

Specifically:
  • Which exact routes should be configured as ESI private cache for Journal3 mini cart?
  • Are there known issues with Journal3 + LSCache where the header cart is still rendered into the full page cache?
  • Is there a best-practice config for OpenCart + LSCache to avoid cart/session leakage into public cache?
Any guidance or working examples would be highly appreciated.

rijstextiles.eu is the test website where you can try out the issue.

Thanks in advance!
 
#3
Thanks for your response! Always great to see such fast reply to a post!

To clarify:
By “mini cart” I mean the standard OpenCart cart in the header (the cart icon with item count and dropdown), which is visible on every page. Not a separate Journal 3 module, but the cart output that Journal 3 renders in the header.

The problems I’m seeing:
  • I’m using OpenCart 3.0.2.0 + Journal 3.1.14 on LiteSpeed Enterprise.
  • With LiteSpeed Full Page Cache enabled, the header cart is cached as part of the page, causing:
    • Wrong cart count (0 items or old items)
    • Cart dropdown showing outdated content
  • The issue also affects:
    • /checkout/cart
    • /checkout/checkout
    • Updating quantities / removing products sometimes doesn’t reflect correctly because cached fragments are served.
  • Even when excluding URLs at server level:
    • LiteSpeed WebAdmin → Server → Cache → Do-Not-Cache URL
      (e.g. /cart/*, /checkout/*, /account/*)
    • And bypass rules in .htaccess
  • LiteSpeed still serves cached versions of pages where the header cart is included.
What I tried:
  • LSCache OpenCart extension ESI:
    • common/cart, common/cart/info, journal3/cart, etc.
    • But the Journal 3 cart is not properly separable as an ESI fragment.
  • Manual ESI include attempts (e.g. <esi:include src="/index.php?route=journal3/cart" />) break rendering and are not processed as expected.
  • The only reliable workaround so far is disabling LSCache completely with:

    CacheLookup Off
    which of course defeats the purpose of using LiteSpeed cache.
So my questions to the community:
  1. Is there a known working setup for LiteSpeed Full Page Cache + OpenCart + Journal 3 where:
    • The header cart is always dynamic
    • Cart and checkout pages are fully excluded from cache
    • Without disabling LSCache globally?
  2. Is there a recommended way to force LiteSpeed to never cache pages that include the cart block, even if they are otherwise cacheable?
  3. Has anyone successfully made the Journal 3 header cart fully AJAX-only to avoid FPC conflicts?
At this point it seems Journal 3’s header/cart integration is not fully compatible with LSCache FPC + ESI in OpenCart.
If anyone has solved this cleanly, I’d really appreciate any guidance or configuration examples.
 
#5
You have a wrong browser cache-control configuration for dynamic sources. Currently it is public, max-age=3600, but should be private, no-cache. This can cause the reported issue as the html content is cached by the browser.
 
#6
We’re running LiteSpeed Web Server (Enterprise 6.3.4) + OpenCart LiteSpeed Cache extension (with ESI enabled).

Problem: cart count / minicart becomes stale. We can reproduce it like this:
  1. First request to homepage: X-LiteSpeed-Cache: miss
  2. Second request: X-LiteSpeed-Cache: hit
  3. After that, the header/minicart shows old quantities, and cart actions appear “not updating” even though the cart POST endpoints return correct no-cache headers.
We noticed the homepage HTML is sometimes returned with:
Cache-Control: public, max-age=3600
So the browser caches the HTML, causing the cached header/minicart markup to remain outdated.

What we already tried / current config
  • LSWS Cache Policy: Check Public Cache = No, Check Private Cache = Yes, Respect Cacheable = No (turning Respect Cacheable ON made the issue much worse immediately).
  • OpenCart LSCache extension:
    • ESI feature enabled
    • ESI module “cart” route: common/cart, ESI with private cache, TTL 60
    • (Ajax Load Shopcart is currently disabled)
  • We added bypass rules for session/cart cookies and force no-cache when bypassing:

<IfModule LiteSpeed>
CacheLookup On
RewriteEngine On

RewriteCond %{HTTP_COOKIE} (^|;\s*)OCSESSID=[^;]+ [NC,OR]
RewriteCond %{HTTP_COOKIE} (^|;\s*)cart=[^;]* [NC]
RewriteRule .* - [E=LSCACHE_BYPASS:1]
</IfModule>

<IfModule mod_headers.c>
Header always set Cache-Control "private, no-cache, no-store, must-revalidate" env=LSCACHE_BYPASS
Header always set Pragma "no-cache" env=LSCACHE_BYPASS
Header always set Expires "0" env=LSCACHE_BYPASS
</IfModule>

Even with this, we still sometimes see public, max-age=3600 on the homepage when it becomes a HIT.

Question:
  • In LSCache for OpenCart, should the header/minicart always be ESI (or Ajax) so the cart never gets baked into the cached homepage?
  • And is there a recommended way in LSWS to prevent browser caching of HTML (while still allowing LSCache server-side caching), especially when a session/cart cookie is present?
We’ll attach screenshots of:
  • the response headers showing public, max-age=3600
  • LSWS cache policy screen
  • OpenCart LSCache ESI settings
Thanks!
 

Attachments

#7
Please separate: Cache-Control is not the same as X-LiteSpeed-Cache-Control! Cache-Control is used for browser cache or caching of static sources. Dynamic sources also have a Cache-Control, but configuration for dynamic sources (the main_document) must be private, no-cache, max-age=0. The X-LiteSpeed-Cache-Control is for configuration of LiteSpeed LScache, the Page Cache.

The cache plugin for OSC controls without any extra configuration what should be cached or not. The configuration in LiteSpeed WebAdmin console to exclude certain paths from caching is for native usage of LScache if there is no cache plugin and conflicts with the cache plugin features, so remove these setting in WebAdmin console.

The rewrite rules in .htaccess for Cache-Control doesn't work as defined, so remove them as well. OSC doesn't cache (browser cache) the main_document, so check any installed 3rd party modules if there is any that sets this wrong Cache-Control. Furthermore, check the Cache-Control configuration in WebAdmin console if the Cache-Control configuration is set to 3600. If yes, remove it!
 
#8
Hi,

Thanks for your reply.

Current situation:
- Main HTML documents return:
Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0
- Images are cached fine (public, max-age=31536000)
- LSCache plugin is installed
- ESI is enabled for common/cart (private cache, TTL 60)
- Cart and checkout endpoints are excluded from cache
- However: enabling full page cache either breaks cart updates or disables cache hits completely.

Questions:
1) Is it correct that the main document should always be:
Cache-Control: private, no-cache, no-store, max-age=0
and LSCache should be controlled only via X-LiteSpeed-Cache-Control?
2) With Journal3: is Ajax Load Shopcart required, or is ESI alone sufficient?
3) Should OCSESSID cookies bypass LSCache or is that handled internally by the LSCache OpenCart plugin?

Goal:
- Cached category/home/product pages
- Live cart (no stale quantities)
- No caching for checkout/account routes etc

Any best-practice setup for LSCache + Journal3 + OpenCart 3 is welcome.
Thanks!
 

Attachments

#9
Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0
Cache-Control is still: public, max-age=3600
screenshot.png


Cache-control for css: public, max-age=604800, no-store
should be: public, max-age=31536000

Cache-control for js: max-age=31536000, public
correct

Cache-Control for images: public, max-age=31536000,public
should be: public, max-age=31536000

You have massive problems with browser cache configuration. That is not typical OSC, so you should contact OSC support to fix this first as the wrong Cache-Control for dynamic sources causes wrong behavior of LScache
 
Top