Skip to content

Instantly share code, notes, and snippets.

@saggy-rakholiya
Created February 22, 2026 09:32
Show Gist options
  • Select an option

  • Save saggy-rakholiya/a902b1cc6afb2e038c75e7bfa8dfbc75 to your computer and use it in GitHub Desktop.

Select an option

Save saggy-rakholiya/a902b1cc6afb2e038c75e7bfa8dfbc75 to your computer and use it in GitHub Desktop.
{
"type": "header",
"content": "Upsell Settings"
},
{
"type": "text",
"id": "upsell_heading",
"label": "Upsell Heading",
"default": "You may also like"
},
{
"type": "select",
"id": "upsell_source",
"label": "Upsell Source",
"options": [
{ "value": "manual", "label": "Manual Selection" },
{ "value": "dynamic", "label": "Dynamic Recommendations" }
],
"default": "manual"
},
{
"type": "product_list",
"id": "upsell_products",
"label": "Select Upsell Products",
"limit": 4
}
{% comment %} Cart Upsell {% endcomment %}
{% liquid assign source = settings.upsell_source %}
{% if source == 'manual' and settings.upsell_products != blank %}
{% assign products_to_show = settings.upsell_products %}
{% endif %}
{% if source == 'manual' and products_to_show != blank %}
<div class="cart-drawer-upsell">
<h3>{{ settings.upsell_heading }}</h3>
<ul class="grid grid--2-col">
{% for product in products_to_show limit: 4 %}
{% assign variant = product.first_available_variant %}
{% if variant %}
<li class="grid__item">
{% if product.featured_media %}
<div class="cart-drawer-media">
<img
src="{{ product.featured_media | image_url: width: 100 }}"
alt="{{ product.featured_media.alt }}" />
</div>
{% endif %}
<div class="cart-drawer-content">
<h3 class="h5">{{ product.title | escape }}</h3>
<button
type="button"
class="button button--secondary button--full-width upsell-add-btn"
data-variant-id="{{ variant.id }}"
{% unless product.available %}disabled{% endunless %}
>
{% if product.available %}
Add to cart
{% else %}
Sold out
{% endif %}
</button>
</div>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{% if settings.upsell_source == 'dynamic' and cart.items.size > 0 %}
<div class="cart-drawer-upsell">
<h3>{{ settings.upsell_heading }}</h3>
<ul id="DynamicUpsellContainer" class="grid grid--2-col"></ul>
</div>
{% endif %}
<script>
document.addEventListener('click', function(e) {
const btn = e.target.closest('.upsell-add-btn');
if (!btn) return;
const variantId = btn.dataset.variantId;
if (!variantId) return;
btn.disabled = true;
btn.textContent = 'Adding...';
fetch('/cart/add.js', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: variantId,
quantity: 1
})
})
.then(() => fetch('/?sections=cart-drawer'))
.then(res => res.json())
.then(data => {
const parser = new DOMParser();
const doc = parser.parseFromString(data['cart-drawer'], 'text/html');
const newDrawer = doc.querySelector('cart-drawer');
document.querySelector('cart-drawer').innerHTML = newDrawer.innerHTML;
})
.catch(err => console.error('Upsell error:', err));
});
</script>
{% if settings.upsell_source == 'dynamic' and cart.items.size > 0 %}
<script>
document.addEventListener("DOMContentLoaded", function () {
const container = document.getElementById("DynamicUpsellContainer");
if (!container) return;
const productId = {{ cart.items.first.product.id }};
fetch(`/recommendations/products.json?product_id=${productId}&limit=4&intent=related`)
.then(res => res.json())
.then(data => {
if (!data.products) return;
data.products.forEach(product => {
const variant = product.variants.find(v => v.available);
if (!variant) return;
const item = `
<li class="grid__item">
${product.featured_image ? `
<div class="cart-drawer-media">
<img src="${product.featured_image}" />
</div>
` : ''}
<div class="cart-drawer-content">
<h3 class="h5">${product.title}</h3>
<button
type="button"
class="button button--secondary button--full-width upsell-add-btn"
data-variant-id="${variant.id}">
Add to cart
</button>
</div>
</li>
`;
container.insertAdjacentHTML("beforeend", item);
});
});
});
</script>
{% endif %}
<style>
.cart-drawer-upsell {
border-top: 1px solid rgba(0,0,0,.1);
}
.cart-drawer-upsell .grid__item {
width: 100%;
max-width: 100%;
display: flex;
align-items: center;
gap: 10px;
padding-right: 10px;
}
.cart-drawer-media {
width: 90px;
}
.cart-drawer-content {
flex: 1;
}
.cart-drawer-upsell .h5{margin-top: 0;}
.cart-drawer-media img{max-width: 100%; width: 100%;}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment