Product page Free
Recently viewed products
Remembers products a shopper opened and shows them in a strip, using the browser only — no app, no tracking pixel.
<div id="recently-viewed" class="recently-viewed" hidden>
<h3>Recently viewed</h3>
<div class="recently-viewed__grid"></div>
</div>
<style>
.recently-viewed{margin:32px 0}
.recently-viewed__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:16px}
.recently-viewed a{text-decoration:none;color:inherit;font-size:13px}
.recently-viewed img{width:100%;height:auto;border-radius:6px;display:block;margin-bottom:6px}
</style>
<script>
(function(){
var KEY = 'recentlyViewed';
var handle = {{ product.handle | json }};
var list = [];
try { list = JSON.parse(localStorage.getItem(KEY)) || []; } catch(e){}
var others = list.filter(function(h){ return h !== handle; });
// Save current product to the front of the list (max 8).
try { localStorage.setItem(KEY, JSON.stringify([handle].concat(others).slice(0,8))); } catch(e){}
var wrap = document.getElementById('recently-viewed');
var grid = wrap.querySelector('.recently-viewed__grid');
var toShow = others.slice(0,4);
if(!toShow.length) return;
Promise.all(toShow.map(function(h){
return fetch('/products/' + h + '.js').then(function(r){ return r.ok ? r.json() : null; }).catch(function(){ return null; });
})).then(function(products){
products.filter(Boolean).forEach(function(p){
var a = document.createElement('a');
a.href = p.url;
a.innerHTML = (p.featured_image ? '<img src="' + p.featured_image + '&width=300" alt="">' : '') +
'<span>' + p.title + '</span>';
grid.appendChild(a);
});
if(grid.children.length) wrap.hidden = false;
});
})();
</script>
Brings back products a visitor already showed interest in, a proven way to recover abandoned browsing. Paste near the bottom of main-product.liquid.
Notes
- History lives in the visitor’s own
localStorage, so nothing is sent to a third party and there is no cookie banner cost. - It fetches each product’s public
/products/{handle}.jsJSON, so titles, prices and images stay current automatically. - The block stays
hiddenuntil at least one other product is available, so first-time visitors see nothing empty.