Skip to content

i have found bug with speculation rules with ajax add to cart #20

Description

@5mehulhelp5

Activity

  1. 5mehulhelp5 commented on Oct 10, 2025

    @5mehulhelp5
    ContributorAuthor
  2. FinnReinhardtBsc commented on Oct 15, 2025

    @FinnReinhardtBsc

    ☝️ Just referencing #23 here, because as I see it, using the Clear-Site-Data header would resolve the above described issue ✅

    → The issue is caused because the speculative load happens before the cart item action takes place (this is true for both prefetch and prerender). When adding the item to the cart, the prefetch / prerender cache is still filled with the initial content. Using the Clear-Site-Data header ensures that the cache is cleared after the cart item action ✅

  3. GrimLink commented on Oct 15, 2025

    @GrimLink
    Contributor

    We have noticed this issue and have an improvement ready for the next Hyvä version.

    For example for the minicart we have this event in the init() of the Alpine function:

    if (document.prerendering) {
      document.addEventListener("prerenderingchange", () => { this.reloadData() }, { once: true });
    } 
  4. JaJuMa commented on Oct 16, 2025

    @JaJuMa
    Contributor

    @FinnReinhardtBsc @GrimLink

    The stale content issue only occurs with prerender, not prefetch, since prerender fully executes JS and renders the page in the background. If an AJAX add to cart action happens after prerendering, the browser may later display outdated content.

    The Hyvä default theme isn’t affected because it uses form posts instead of AJAX.

    I see using Clear-Site-Data works but isn’t optimal, because it depends on browser behavior and discards reusable prerendered content.

    We’ve fixed this in PR #24 by updating data from local storage right after prerender. This ensures the prerendered content stays fresh without clearing the entire speculation cache.

    Feel free to give us some comments or suggestions on this approach.

  5. GrimLink commented on Oct 16, 2025

    @GrimLink
    Contributor

    @JaJuMa your right this happens just with prerender.

    This is a unique case to Hyvä since we offer from Hyvä UI, the Ajax Add to Cart.
    Allowing you to add products without a page refresh, this why this issue is visible.

    Good to see a fix a fix was made @JaJuMa 👍

  6. FinnReinhardtBsc commented on Oct 16, 2025

    @FinnReinhardtBsc

    Thanks for your insights, @GrimLink & @JaJuMa 👍

    I stand corrected, that this issue only applies to prerenders. It appears that my local configuration had prerendering enabled, but I assumed it was set to prefetch, as is usually the case.

    Here's my take on this:

    • Generally, performance in most cases outweighs consistency
      • Just look at Amazon - they don't even bother refreshing the cart when you add a product and navigate back via BF-Cache
      • Amazon solves this by providing a dedicated /cart page, which will not be served from the BF-Cache

    → ✅ Handling this issue is the cherry on top for the customer 🍒 🥇 😄


    Here's what I like about your proposed solution:

    • ✅ It does not discard the prerendered page
    • ✅ It's simple and applicable to both Hyva & Luma
    • ✅ It uses few bandwidth for the section data update (if any at all)
    • ✅ For Hyva, using the event to reload the section data is a robust solution, so there are usually not many side effects associated with this - the UI updates automatically because of the associated events

    As mentioned before, this issue is mainly relevant for idempotent AJAX calls (e.g. from the AJAX add to cart extension or Hyva UI implementation).

    → When products / cart items are updated via form and thus triggering a page reload, the prerenderCache is certainly discarded. In that sense, the behavior is similar to sending the Clear-Site-Data header after an idempotent action.

    Here's what I like about my provided solution:

    • ✅ It applies only to the events where a cart item change has occurred. All other prerenders are not affected
    • ✅ Although the prerenderCache is discarded, the underlying page will most certainly be cached by Varnish
      • Thus, prerendering the page again will happen quickly and not cause a lot of strain on the server. Of course this also applies to the case when the cart items have been updated via form
    • ✅ The solution is consistent when multiple tabs are opened on the same device, as the prerenderCache invalidation applies to the entire website

    Here are the the differences and nuances that lead me to favor either solution.

    • The JS-Solution using the prerenderingChange-Event applies to all prerendered pages. Regardless of whether they are using AJAX or forms for the cart item updates
      • Thus, this affects subsequent prerender navigations for both AJAX, and form based cart item updates
      • Section data may be loaded unnecessarily for each prerendered page
        • ❌ If the section data update requires an additional uncached request, I would recommend using the Clear-Site-Data approach
        • ✅ If the Section data correctly updates from the localstorage (which it should, according to the logic defined in the private-content.phtml), I would prefer the JS-solution

    This might be worth testing.


    TL;DR

    • If the section data is correctly updated from localstorage, @JaJuMa's JS approach is the way to go 🥇
    • If it required an additional uncached request to the server, I would prefer the Clear-Site-Data approach
  7. JaJuMa commented on Oct 17, 2025

    @JaJuMa
    Contributor

    @FinnReinhardtBsc Thanks a lot for this detailed and extensive reasoning.

    Really nice deep-dive into speculation rules! 👏

    Please allow me to add a few comments:

    • The Clear-Site-Data header is currently baseline “Newly Available”, caniuse shows around 93% browser coverage.
      However, the Clear-Site-Data:"prerenderCache" directive (which would be the relevant one here) is still experimental and only covered by roughly 65% of browsers accoding to caniuse.
      → I’d assume that means it’s not yet ready for production use in Mage-OS, right?

    • Regarding

      “prerenderCache invalidation applies to the entire website”

      The JS solution effectively covers the whole site as well, since it ensures stale data is updated automatically whenever a prerendered page becomes visible.

    • And yes, with the JS solution, section data is correctly updated from localStorage, leveraging Magento’s Customer Section Data mechanism.

    • Another reason I prefer the JS approach:
      It’s consistent with the BFCache implementation, which follows the same “refresh on activation” concept.
      It’s aligned with Magento’s architecture, using Customer Section Data.
      And it avoids introducing or managing additional HTTP headers, which aren’t exactly the “home turf” for most Magento devs 😉

    • That said, the Clear-Site-Data approach can still be useful as a fallback for very specific cases (e.g., when AJAX updates are deeply tied to cross-tab consistency or non-section data).
      But for the common Hyvä / AJAX add-to-cart flow, the JS-based refresh on prerender activation clearly feels like the cleaner and more future-proof direction.

  8. rhoerr commented on Nov 1, 2025

    @rhoerr
    Member

    This should be resolved with #24. Thank you all for the contributions and deep discussion of the matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions