Description
- clear products from cart after 10 minutes
- buy me a coffee
#1. Install Code
#1.1. You can use this code to Code Injection > Footer
<!-- 07.26c22v1 Clear Product After 10 Minutes -->
<script>
window.CartAutoClearConfig = {
minutes: 0.1,
clearOnNewSession: true,
resetTimerOnCartChange: true,
debug: true
};
</script>
<script>
(function () {
'use strict';
if (window.top !== window.self) return;
var cfg = window.CartAutoClearConfig;
if (!cfg) return;
var TS_KEY = 'ssCacTs';
var QTY_KEY = 'ssCacQty';
var SESSION_KEY = 'ssCacSession';
var PENDING_KEY = 'ssCacPending';
var timerId = null;
var evalDebounce = null;
var clearing = false;
function log() {
if (!cfg.debug) return;
var a = Array.prototype.slice.call(arguments);
a.unshift('[CAC]');
console.log.apply(console, a);
}
function isEditMode() {
return document.body && document.body.classList.contains('sqs-edit-mode-active');
}
function isCartPage() {
return (document.body && document.body.id === 'cart') || !!document.getElementById('sqs-cart-root');
}
function isCheckout() {
return /checkout/i.test(location.pathname);
}
function windowMs() {
return (Number(cfg.minutes) || 10) * 60000;
}
function parseCartFromDoc(doc) {
var s = doc.querySelector('#sqs-cart-root script[type="application/json"]');
if (!s) return null;
try { return JSON.parse(s.textContent); } catch (e) { return null; }
}
async function getCart() {
if (isCartPage()) {
var local = parseCartFromDoc(document);
if (local) return local;
}
try {
var res = await fetch('/cart', { credentials: 'same-origin' });
var text = await res.text();
var doc = new DOMParser().parseFromString(text, 'text/html');
return parseCartFromDoc(doc);
} catch (e) {
return null;
}
}
function entryIds(cart) {
if (!cart || !cart.cart || !Array.isArray(cart.cart.items)) return [];
return cart.cart.items.map(function (i) { return i.id; }).filter(Boolean);
}
function totalQty(cart) {
if (!cart || !cart.cart || !Array.isArray(cart.cart.items)) return 0;
return cart.cart.items.reduce(function (n, i) { return n + (Number(i.quantity) || 0); }, 0);
}
function updateBadges() {
document.querySelectorAll('.sqs-cart-quantity').forEach(function (el) { el.textContent = '0'; });
}
function clearState() {
localStorage.removeItem(TS_KEY);
localStorage.removeItem(QTY_KEY);
}
function runClear(doc, resolve) {
var tries = 0;
var sawButtons = false;
var iv = setInterval(function () {
tries++;
var btns, rows;
try {
btns = doc.querySelectorAll('.cart-row-remove, [data-test="remove-item"]');
rows = doc.querySelectorAll('[data-testid="cart-table-row"], .cart-row');
} catch (e) {
clearInterval(iv);
resolve(false);
return;
}
if (btns.length) {
sawButtons = true;
btns[0].click();
return;
}
if (sawButtons && rows.length === 0) {
clearInterval(iv);
resolve(true);
return;
}
if (!sawButtons) {
var c = parseCartFromDoc(doc);
if (c && entryIds(c).length === 0) {
clearInterval(iv);
resolve(true);
return;
}
}
if (tries > 90) {
clearInterval(iv);
resolve(sawButtons && btns.length === 0);
}
}, 350);
}
function clearViaIframe() {
return new Promise(function (resolve) {
var iframe = document.createElement('iframe');
iframe.setAttribute('aria-hidden', 'true');
iframe.style.cssText = 'position:absolute;width:0;height:0;border:0;left:-9999px;top:-9999px;opacity:0;';
iframe.src = '/cart';
var settled = false;
function finish(ok) {
if (settled) return;
settled = true;
clearTimeout(hardStop);
try { iframe.remove(); } catch (e) {}
resolve(ok);
}
var hardStop = setTimeout(function () { finish(false); }, 35000);
iframe.onload = function () {
var doc;
try {
doc = iframe.contentDocument || iframe.contentWindow.document;
} catch (e) {
finish(false);
return;
}
if (!doc) { finish(false); return; }
runClear(doc, finish);
};
document.body.appendChild(iframe);
});
}
async function clearCart(reason) {
if (clearing) return;
clearing = true;
log('clear triggered:', reason);
var cart = await getCart();
if (!entryIds(cart).length) {
clearState();
localStorage.removeItem(PENDING_KEY);
clearing = false;
return;
}
if (isCartPage()) {
runClear(document, function (ok) {
if (ok) {
clearState();
localStorage.removeItem(PENDING_KEY);
updateBadges();
log('cleared on cart page');
}
clearing = false;
});
return;
}
var ok = await clearViaIframe();
if (ok) {
clearState();
localStorage.removeItem(PENDING_KEY);
updateBadges();
log('cleared via iframe');
} else {
localStorage.setItem(PENDING_KEY, '1');
log('iframe clear failed, deferred to cart page');
}
clearing = false;
}
function schedule(remaining) {
if (timerId) clearTimeout(timerId);
timerId = setTimeout(function () { clearCart('timer'); }, Math.max(0, remaining));
log('scheduled clear in', Math.round(remaining / 1000), 's');
}
async function evaluate() {
if (isCheckout() || isEditMode()) return;
var cart = await getCart();
var ids = entryIds(cart);
var qty = totalQty(cart);
if (!ids.length) {
clearState();
return;
}
if (cfg.clearOnNewSession && !sessionStorage.getItem(SESSION_KEY)) {
sessionStorage.setItem(SESSION_KEY, '1');
clearCart('new-session');
return;
}
if (!sessionStorage.getItem(SESSION_KEY)) sessionStorage.setItem(SESSION_KEY, '1');
var ts = Number(localStorage.getItem(TS_KEY)) || 0;
var lastQty = Number(localStorage.getItem(QTY_KEY));
if (!ts || (cfg.resetTimerOnCartChange && qty !== lastQty)) {
ts = Date.now();
}
localStorage.setItem(TS_KEY, String(ts));
localStorage.setItem(QTY_KEY, String(qty));
var remaining = windowMs() - (Date.now() - ts);
if (remaining <= 0) {
clearCart('expired');
return;
}
schedule(remaining);
}
function queueEvaluate() {
if (evalDebounce) clearTimeout(evalDebounce);
evalDebounce = setTimeout(evaluate, 400);
}
function watchBadge() {
var box = document.querySelector('.icon-cart-quantity') || document.body;
var obs = new MutationObserver(queueEvaluate);
obs.observe(box, { childList: true, subtree: true, characterData: true });
}
function handlePending(done) {
if (isCartPage() && localStorage.getItem(PENDING_KEY)) {
runClear(document, function () {
localStorage.removeItem(PENDING_KEY);
clearState();
updateBadges();
if (done) done();
});
return true;
}
return false;
}
function init() {
if (isEditMode()) return;
if (document.documentElement.dataset.cacDone === '1') {
if (!handlePending()) evaluate();
return;
}
document.documentElement.dataset.cacDone = '1';
watchBadge();
if (!handlePending(evaluate)) evaluate();
}
window.addEventListener('load', init);
window.addEventListener('mercury:load', init);
})();
</script>

#1.2. Update Minutes here
- 0.1 = 10 seconds
- if you want to set 10 minutes, just change 0.1 to 10
minutes: 0.1,

#2. Customize
nothing now