Cross-Sell Products are a great way to increase revenue and average order value. Use the following Liquid code snippet on your Shopify theme’s product template to display Cross-Sell Products synced via Partbot.
partbot-cross-sell-product.liquid
{%- assign max_columns = max_columns | default: 3 -%}
{%- assign container_classes = container_classes
| default: 'mt-8 border-dashed border-gray-500 border-t border-b divide-y divide-gray-500 divide-dashed'
-%}
{%- assign cross_sell_types = cross_sell_types | default: 'required' | split: ',' -%}
{%- assign variant = product.selected_or_first_available_variant -%}
{%- if variant.metafields.partbot.cross_sell_products -%}
{%- assign cross_sell_products = variant.metafields.partbot.cross_sell_products.value -%}
{% if cross_sell_products == blank %}
{% assign cross_sell_products = variant.metafields.partbot.cross_sell_products %}
{% endif %}
{%- assign filtered_cross_sell_products = '' | split: '' -%}
{%- for type in cross_sell_types -%}
{%- assign type_products = cross_sell_products.products | where: 'relationship_type', type -%}
{%- assign filtered_cross_sell_products = filtered_cross_sell_products | concat: type_products -%}
{%- endfor -%}
{%- if filtered_cross_sell_products.size > 0 -%}
<div class="{{ container_classes }}">
<div class="py-8">
{%- if cross_sell_types.size == 1 and cross_sell_types[0] == 'required' -%}
<h3 class="font-bold text-white text-xl tracking-tight">
You'll need {{ filtered_cross_sell_products.size | pluralize: 'this', 'these' }}...
</h3>
{%- else -%}
<h3 class="font-bold text-white text-xl tracking-tight">
We also recommend {{ filtered_cross_sell_products.size | pluralize: 'this', 'these' }}...
</h3>
{%- endif -%}
<div class="mt-3 grid grid-cols-2 md:grid-cols-{{ max_columns }} gap-x-5 gap-y-8">
{% for item in filtered_cross_sell_products %}
{%- assign csp = all_products[item.shopify_product.handle] -%}
{% if csp.id != blank %}
<div class="h-full flex flex-col justify-between">
<div class="relative">
<a href="{{csp.url}}"
class="block group w-full bg-white rounded border border-gray-200 overflow-hidden aspect-square"
>
<img
src="{{csp.featured_image | image_url: width: 300, height: 300 }}"
alt="{{csp.featured_image.alt}}"
width="300px"
height="300px"
class="p-2 w-full h-full object-center object-cover group-hover:opacity-75"
>
</a>
<div class="{% if item.relationship_type == 'required' %}bg-red-600{% else %}bg-black{% endif %} inline-block whitespace-nowrap rounded text-gray-100 text-xs px-2 py-1 absolute top-1 left-1">
{{ item.relationship_type | capitalize }}
</div>
<a href="{{csp.url}}" class="text-gray-500 block tracking-tight leading-0 text-xs my-3">
{{- csp.title | truncate: 120, '...' -}}
</a>
</div>
<div class="whitespace-nowrap text-gray-300 font-bold text-sm mb-3">
{% if csp.price_varies %}
From: {{ csp.price | money }}
{% else %}
{{ csp.price | money }}
{% endif %}
</div>
{%- if csp.available -%}
<button
data-variant-id="{{ item.shopify_variant.id }}"
data-title="{{ csp.title }}"
data-image="
{%- if
csp.featured_image -%}{{ variant.featured_image.src }}{%- endif -%}
"
class="partbot-cross-sell-btn block w-full btn-pill"
>
Add to Cart
</button>
{%- else -%}
<button disabled class="btn-pill block w-full opacity-50 pointer-events-none">Sold Out</button>
{%- endif -%}
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
{%- endif -%}
{%- endif -%}
<script>
function crossSellProducts() {
this.cartDrawer = document.querySelector('cart-drawer');
// Add click events to add to cart
const crossSellButtons = document.querySelectorAll('.partbot-cross-sell-btn');
crossSellButtons.forEach((product) => {
product.addEventListener('click', (e) => {
e.preventDefault();
let btn = e.target;
const image = btn.dataset.image;
const title = btn.dataset.title;
const body = JSON.stringify({
items: [
{
id: e.target.dataset.variantId,
},
],
});
console.log('body', body);
fetch(`${routes.cart_add_url}`, {
...fetchConfig('javascript'),
body,
})
.then((response) => response.json())
.then((parsedState) => {
this.cartDrawer.loadCart();
})
.catch((e) => {
console.error('cross-sell-products error', e);
})
.finally(() => {
this.cartDrawer.open();
});
});
});
}
document.addEventListener('DOMContentLoaded', crossSellProducts);
</script>
We’ve added some opinionated TailwindCSS styles to the above code, but you should customise and style to match your website theme and specific needs. All Shopify product fields are accessible via csp
.
Then render the snippet on your product page, like so:
{% render 'partbot-cross-sell-products',
cross_sell_types: 'related,compatible,alternate'
max_columns: 6,
container_classes: 'your-container-classes'
%}