script tag XHR event listener for monitoring cart activities does not work anymore

4.1k Views Asked by At

I have an app which will add this script tag into the store.

In the past I use script tag with this script to monitor customer's cart activities. When the script tag detect a XHR, it will fire some data to my backend.

var oldXHR = window.XMLHttpRequest;

function newXHR() {
  console.log('XHR detected!')
  var realXHR = new oldXHR();
  realXHR.addEventListener(
    "load",
    function () {
      if (realXHR.readyState == 4 && realXHR.status == 200) {
        if (realXHR._url === "/cart.js" || realXHR._url === "/cart/change.js") {
           // do something....
        }
      }
    },
    false
  );
  return realXHR;
}
window.XMLHttpRequest = newXHR;

But today I don't know why the action of changing the cart and adding item into cart cannot trigger the XHR listener anymore. However, this script tag is still working in my old store. But if I install it to a new store, it does not trigger anything. I check the script tag is normally running in that new store, but the problem is the XHR listener did not trigger.

Anyone have some ideas?

1

There are 1 best solutions below

3
Bilal Akbar On

I configured a new Dev store on Shopify and tried your code as well as similar code from my other answer that listens to XHR calls. But it did not work. On debugging a bit, I found that it listens to calls made using jQuery or XHR but not for Shopify Cart. This led me to find out that cart updates were done using Fetch API. So, we also need to listen to all fetch calls. It can be done so using

(function(ns, fetch) {
  if (typeof fetch !== 'function') return;

  ns.fetch = function() {
    const response = fetch.apply(this, arguments);

    response.then(res => {
      if ([
          `${window.location.origin}/cart/add.js`,
          `${window.location.origin}/cart/update.js`,
          `${window.location.origin}/cart/change.js`,
          `${window.location.origin}/cart/clear.js`,
        ].includes(res.url)) {
        res.clone().json().then(data => console.log(data));
      }
    });

    return response;
  }

}(window, window.fetch))

If it matches the URL, you can call your function with custom data. The URL logic matching is not tested thoroughly.

The above code is working for me on latest Shopify Debut theme.

Fetch override code from Yury Tarabanko