can i be notified of cookie changes in client side javascript

One option is to write a function that periodically checks the cookie for changes:

var checkCookie = function() {

    var lastCookie = document.cookie; // 'static' memory between function calls

    return function() {

        var currentCookie = document.cookie;

        if (currentCookie != lastCookie) {

            // something useful like parse cookie, run a callback fn, etc.

            lastCookie = currentCookie; // store latest cookie

        }
    };
}();

window.setInterval(checkCookie, 100); // run every 100 ms
  • This example uses a closure for persistent memory. The outer function is executed immediately, returning the inner function, and creating a private scope.
  • window.setInterval

Method 1: Periodic Polling

Poll document.cookie

function listenCookieChange(callback, interval = 1000) {
  let lastCookie = document.cookie;
  setInterval(()=> {
    let cookie = document.cookie;
    if (cookie !== lastCookie) {
      try {
        callback({oldValue: lastCookie, newValue: cookie});
      } finally {
        lastCookie = cookie;
      }
    }
  }, interval);
}

Usage

listenCookieChange(({oldValue, newValue})=> {
  console.log(`Cookie changed from "${oldValue}" to "${newValue}"`);
}, 1000);

document.cookie = 'a=1';

Method 2: API Interception

Intercept document.cookie

(()=> {
  let lastCookie = document.cookie;
  // rename document.cookie to document._cookie, and redefine document.cookie
  const expando = '_cookie';
  let nativeCookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
  Object.defineProperty(Document.prototype, expando, nativeCookieDesc);
  Object.defineProperty(Document.prototype, 'cookie', {
    enumerable: true,
    configurable: true,
    get() {
      return this[expando];
    },
    set(value) {
      this[expando] = value;
      // check cookie change
      let cookie = this[expando];
      if (cookie !== lastCookie) {
        try {
          // dispatch cookie-change messages to other same-origin tabs/frames
          let detail = {oldValue: lastCookie, newValue: cookie};
          this.dispatchEvent(new CustomEvent('cookiechange', {
            detail: detail
          }));
          channel.postMessage(detail);
        } finally {
          lastCookie = cookie;
        }
      }
    }
  });
  // listen cookie-change messages from other same-origin tabs/frames
  const channel = new BroadcastChannel('cookie-channel');
  channel.onmessage = (e)=> {
    lastCookie = e.data.newValue;
    document.dispatchEvent(new CustomEvent('cookiechange', {
      detail: e.data
    }));
  };
})();

Usage

document.addEventListener('cookiechange', ({detail: {oldValue, newValue}})=> {
  console.log(`Cookie changed from "${oldValue}" to "${newValue}"`);
});

document.cookie = 'a=1';

Notes

  1. not for IE
  2. require BroadcastChannel polyfill for Safari

Conclusion

| Metric \ Method  | Periodic Polling            | API Interception |
| ---------------- | --------------------------- | ---------------- |
| delay            | depends on polling interval | instant          |
| scope            | same-domain                 | same-origin      |

I think my way is better. I wrote a custom event for detect when cookie is chanced:

const cookieEvent = new CustomEvent("cookieChanged", {
  bubbles: true,
  detail: {
    cookieValue: document.cookie,
    checkChange: () => {
      if (cookieEvent.detail.cookieValue != document.cookie) {
        cookieEvent.detail.cookieValue = document.cookie;
        return 1;
      } else {
        return 0;
      }
    },
    listenCheckChange: () => {
      setInterval(function () {
        if (cookieEvent.detail.checkChange() == 1) {
          cookieEvent.detail.changed = true;
          //fire the event
          cookieEvent.target.dispatchEvent(cookieEvent);
        } else {
          cookieEvent.detail.changed = false;
        }
      }, 1000);
    },
    changed: false
  }
});

/*FIRE cookieEvent EVENT WHEN THE PAGE IS LOADED TO
 CHECK IF USER CHANGED THE COOKIE VALUE */

document.addEventListener("DOMContentLoaded", function (e) {
  e.target.dispatchEvent(cookieEvent);
});

document.addEventListener("cookieChanged", function (e) {
  e.detail.listenCheckChange();
  if(e.detail.changed === true ){
    /*YOUR CODE HERE FOR DO SOMETHING 
      WHEN USER CHANGED THE COOKIE VALUE */
  }
});