LIQUIDshopifybeginner
Shopify Product Recommendations
Display related products using Shopify's built-in recommendation engine
Faisal Yaqoob
January 9, 2025
#shopify#liquid#recommendations#related-products#upsell
Code
liquid
1 {% comment %} 2 Product Recommendations Section 3 Add this to your product template or create as a section 4 {% endcomment %} 5
6 <div class="product-recommendations" data-product-id="{{ product.id }}"> 7 <div class="recommendations-loading"> 8 <p>Loading recommendations...</p> 9 </div> 10 </div> 11
12 <script> 13 document.addEventListener('DOMContentLoaded', function() { 14 const container = document.querySelector('.product-recommendations'); 15 const productId = container.dataset.productId; 16
17 // Fetch recommendations using Section Rendering API 18 fetch(`/recommendations/products?product_id=${productId}&limit=4§ion_id=product-recommendations`) 19 .then(response => response.text()) 20 .then(html => { 21 if (html.trim().length) { 22 container.innerHTML = html; 23 } else { 24 container.style.display = 'none'; 25 } 26 }) 27 .catch(error => { 28 console.error('Error loading recommendations:', error); 29 container.style.display = 'none'; 30 }); 31 }); 32 </script> 33
34 <style> 35 .product-recommendations { 36 margin: 60px 0; 37 } 38
39 .recommendations-loading { 40 text-align: center; 41 padding: 40px; 42 color: #999; 43 } 44 </style>
Shopify Product Recommendations
Display related products on your product pages using Shopify's built-in recommendation engine. This uses the Section Rendering API to fetch recommendations dynamically.
{% comment %}
Product Recommendations Section
Add this to your product template or create as a section
{% endcomment %}
<div class="product-recommendations" data-product-id="{{ product.id }}">
<div class="recommendations-loading">
<p>Loading recommendations...</p>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector('.product-recommendations');
const productId = container.dataset.productId;
// Fetch recommendations using Section Rendering API
fetch(`/recommendations/products?product_id=${productId}&limit=4§ion_id=product-recommendations`)
.then(response => response.text())
.then(html => {
if (html.trim().length) {
container.innerHTML = html;
} else {
container.style.display = 'none';
}
})
.catch(error => {
console.error('Error loading recommendations:', error);
container.style.display = 'none';
});
});
</script>
<style>
.product-recommendations {
margin: 60px 0;
}
.recommendations-loading {
text-align: center;
padding: 40px;
color: #999;
}
</style>
Create Recommendations Section
Create a new section file sections/product-recommendations.liquid:
{% if recommendations.performed %}
{% if recommendations.products_count > 0 %}
<div class="product-recommendations-inner">
<h2 class="recommendations-heading">You May Also Like</h2>
<div class="recommendations-grid">
{% for product in recommendations.products %}
<div class="recommendation-item">
<a href="{{ product.url }}" class="recommendation-link">
{% if product.featured_image %}
<img
src="{{ product.featured_image | img_url: '400x' }}"
alt="{{ product.featured_image.alt | escape }}"
loading="lazy"
class="recommendation-image"
>
{% endif %}
<h3 class="recommendation-title">{{ product.title }}</h3>
<div class="recommendation-price">
{% if product.compare_at_price > product.price %}
<span class="price-compare">{{ product.compare_at_price | money }}</span>
<span class="price-sale">{{ product.price | money }}</span>
{% else %}
<span class="price">{{ product.price | money }}</span>
{% endif %}
</div>
</a>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endif %}
Styling
.recommendations-heading {
font-size: 28px;
font-weight: 700;
margin-bottom: 30px;
text-align: center;
}
.recommendations-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 30px;
}
.recommendation-item {
position: relative;
}
.recommendation-link {
display: block;
text-decoration: none;
color: inherit;
transition: transform 0.3s ease;
}
.recommendation-link:hover {
transform: translateY(-5px);
}
.recommendation-image {
width: 100%;
height: auto;
aspect-ratio: 1;
object-fit: cover;
border-radius: 8px;
margin-bottom: 15px;
}
.recommendation-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 8px;
}
.recommendation-price {
font-size: 18px;
font-weight: 700;
}
.price-compare {
text-decoration: line-through;
color: #999;
margin-right: 8px;
}
.price-sale {
color: #e53935;
}
Alternative: Manual Related Products
If you prefer to manually select related products using metafields:
{% if product.metafields.custom.related_products %}
<div class="related-products">
<h2>Related Products</h2>
<div class="related-grid">
{% for product_handle in product.metafields.custom.related_products.value %}
{% assign related_product = all_products[product_handle] %}
<div class="related-item">
<a href="{{ related_product.url }}">
<img src="{{ related_product.featured_image | img_url: '300x' }}" alt="{{ related_product.title }}">
<h3>{{ related_product.title }}</h3>
<p>{{ related_product.price | money }}</p>
</a>
</div>
{% endfor %}
</div>
</div>
{% endif %}
Benefits
- Automatic: Shopify's algorithm selects related products
- Performant: Uses Section Rendering API for fast loading
- Customizable: Full control over layout and styling
- Increases Sales: Effective upselling and cross-selling
Related Snippets
Shopify Variant Selector with Images
Dynamic variant selector that updates product images and price in real-time
LIQUIDshopifyintermediate
liquidPreview
{% comment %}
Product Variant Selector
Add this to your product template
{% endcomment %}
...#shopify#liquid#variants+2
1/9/2025
View
Shopify AJAX Add to Cart
Add products to cart without page reload using Shopify AJAX API
JAVASCRIPTshopifyintermediate
javascriptPreview
// Add to cart with AJAX
function addToCart(variantId, quantity = 1) {
const formData = {
items: [{
...#shopify#ajax#cart+2
1/9/2025
View