
Credits usage has reached0%.
Expected to run out of credits in0 days. If credits usage limit is exceeded, SKUs will automatically remove the integrated custom features.
Make Shopify’s Cart Display Custom Data More Effectively

Let’s check out how it looks after the changes.
Alright, let’s kick off the tutorial!
Log into your Shopify admin, then head to the Online Store > Themes page.
We’ll use Shopify’s default Dawn theme as an example to copy, tap the "More" button to jump into the code editing page.
Select the snippets folder and tap the "New File" button.
Create a file called “customeow-data.liquid”.
Copy and paste the code below into the “customeow-data.liquid” file.
{% comment %}
Renders CustoMeow Custom Data
Accepts:
- properties: {Array} Cart item properties
- title: {String} Custom data title (optional)
- enable_dark: {Boolean} Website dark mode, default is false (optional)
- text_color: {String} text color, hex or rgba, default is oklch(37.3% .034 259.733), enable_dark text color is white. (optional)
- preview_font_size: {Number} Preview text font size (optional), 12~16, default is 12
- preview_image_width: {Number} Preview image width (optional), default is 60
- preview_image_radius: {Number} Preview image border radius (optional), default is 6
- enable_modal: {Boolean} Show image modal when true
- modal_background_color: '' {String} Image modal background color, hex or rgba, default is black (optional)
- cart_item_id: {String} Cart item id (optional)
- cart_item_image_classname: {String} Preview first image cover thumbnail (optional)
Usage:
{% render 'customeow-data', properties: item.properties, title: 'Your personalization', preview_font_size: 12, preview_image_width: 60, preview_image_radius: 6, enable_modal: true %}
{% endcomment %}
{%- liquid
assign show_title = true
unless title
assign show_title = false
endunless
assign is_dark = false
if enable_dark
assign is_dark = true
endif
assign label_color = 'oklch(37.3% .034 259.733)'
if text_color
assign label_color = text_color
endif
if preview_font_size
if preview_font_size < 12 or preview_font_size > 16
assign preview_font_size = 12
endif
else
assign preview_font_size = 12
endif
unless preview_image_width
assign preview_image_width = 60
endunless
assign preview_modal_radius = 12
assign preview_modal_inner_radius = 11
if preview_image_radius
assign preview_modal_radius = preview_image_radius | times: 2
assign preview_modal_inner_radius = preview_modal_radius | minus: 1
endif
assign enable_image_modal = true
unless enable_modal
assign enable_image_modal = false
endunless
unless modal_background_color
assign modal_background_color = 'black'
endunless
assign property_texts = ''
assign property_orginal_images = ''
for property in properties
if property.first == 'preview.texts'
assign property_texts = property.last | split: ','
elsif property.first == 'preview.effects' or property.first == 'preview.images'
if property_orginal_images.size > 0
assign property_orginal_images_last = ',' | append: property.last
assign property_orginal_images = property_orginal_images | append: property_orginal_images_last
else
assign property_orginal_images = property.last
endif
endif
endfor
assign property_images = property_orginal_images | split: ','
-%}
{% if enable_image_modal %}
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
{% endif %}
<style>
.cm-customization {
margin-top: 20px;
}
.cm-customization-title {
font-size: 14px;
font-weight: 500;
color: {% if is_dark %}white{% else %}{{ label_color }}{% endif %};
}
.cm-customization-container {
padding: 4px 0 8px;
display: none;
}
.cm-customization-container.active {
display: block;
}
.cm-customization-texts {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.cm-customization-texts-tag {
padding: 2px 4px;
border-radius: 4px;
background-color: {% if is_dark %}rgba(255,255,255,0.06){% else %}rgba(0,0,0,0.06){% endif %};
color: {% if is_dark %}white{% else %}{{ label_color }}{% endif %};
font-size: {{ preview_font_size }}px;
}
.cm-customization-images {
margin-top: 8px;
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.cm-customization-images-thumbnail {
width: {{ preview_image_width }}px;
border-radius: {{ preview_image_radius }}px;
overflow: hidden;
position: relative;
aspect-ratio: 1 / 1;
}
.cm-customization-images-thumbnail.cursor-pointer {
cursor: pointer;
}
.cm-customization-images-thumbnail:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 1px solid {% if is_dark %}rgba(255,255,255,0.2){% else %}rgba(0,0,0,0.2){% endif %};
border-radius: {{ preview_image_radius }}px;
}
.cm-customization-images-thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
}
.cm-customization-images-thumbnail-mask {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background-color: rgba(0,0,0,0.4);
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
transition: all cubic-bezier(0.33, 1, 0.68, 1) 200ms;
}
.cm-customization-images-thumbnail:hover .cm-customization-images-thumbnail-mask {
opacity: 1;
}
.cm-customization-images-thumbnail-svg {
width: 20px;
height: 20px;
}
.cm-customization-transition {
transition: all 200ms cubic-bezier(0.33, 1, 0.68, 1);
}
.cm-customization-bg-from {
opacity: 0;
}
.cm-customization-bg-to {
opacity: 1;
}
.cm-customization-modal-from {
opacity: 0;
transform: scale(0.94);
}
.cm-customization-modal-to {
opacity: 1;
transform: scale(1);
}
.cm-customization-close-from {
opacity: 0;
transform: translateY(10px);
}
.cm-customization-close-to {
opacity: 1;
transform: translateY(0);
}
.cm-customization-modal {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
z-index: 99999999;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.cm-customization-modal-bg {
width: 100%;
height: 100%;
position: absolute;
background-color: rgba(0,0,0,0.8);
z-index: 0;
}
.cm-customization-splide {
width: 80%;
aspect-ratio: 1 / 1;
background-color: {{ modal_background_color }};
position: relative;
z-index: 1;
border-radius: {{ preview_modal_radius }}px;
overflow: hidden;
}
.cm-customization-splide:before {
content: '';
position: absolute;
left: 1px;
right: 1px;
top: 1px;
bottom: 1px;
border: 1px solid rgba(255,255,255,0.16);
border-radius: {{ preview_modal_inner_radius }}px;
z-index: 10;
pointer-events: none;
}
.cm-customization-splide .cm-customization-splide-frame,
.cm-customization-splide img {
width: 100%;
height: 100%;
object-fit: contain;
}
.cm-customization-splide .cm-customization-splide-frame {
aspect-ratio: 1 / 1;
position: relative;
}
.cm-customization-splide .cm-customization-splide-button {
display: none;
}
.cm-customization-splide:hover .cm-customization-splide-button {
display: block;
}
.cm-customization-splide-button {
width: 36px;
height: 36px;
background-color: white;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
border-radius: 100px;
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
}
.cm-customization-splide-button span {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.cm-customization-splide-button span svg {
width: 16px;
height: 16px;
fill: oklch(44.6% 0.03 256.802);
}
.cm-customization-splide-left {
left: 12px;
}
.cm-customization-splide-right {
right: 12px;
}
.cm-customization-modal-close {
width: 36px;
height: 36px;
border: 2px solid white;
border-radius: 100%;
position: relative;
z-index: 5;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
cursor: pointer;
}
.cm-customization-modal-close svg {
width: 20px;
height: 20px;
}
@media (width >= 640px) {
.cm-customization-splide {
width: 480px;
}
}
{% if cart_item_id and cart_item_image_classname %}
#{{ cart_item_id }} .{{ cart_item_image_classname }} {
position: relative;
}
#{{ cart_item_id }} .{{ cart_item_image_classname }}:before {
content: '';
width: 100%;
height: 100%;
background-image: url({{ property_orginal_images | split: ',' | first }});
background-position: center top;
background-size: contain;
background-color: white;
background-repeat: no-repeat;
position: absolute;
left: 0;
top: 0;
}
{% endif %}
</style>
<div class="cm-customization">
{%- if show_title -%}
<div class="cm-customization-title">{{ title }}</div>
{%- endif -%}
<div class="cm-customization-container{% unless enable_image_modal %} active{% endunless %}" :class="init ? 'active' : ''"
x-data="{
init: false,
openModal: false,
previewIndex: 0,
imageArray: [],
currentImageUrl: '',
showSlideLeftButton: false,
showSlideRightButton: false
}"
x-init="init = true">
{% comment %} texts {% endcomment %}
{%- if property_texts.size > 0 -%}
<div class="cm-customization-texts">
{%- for item in property_texts -%}
<span class="cm-customization-texts-tag">{{ item }}</span>
{%- endfor -%}
</div>
{%- endif -%}
{% comment %} preview thumbnail {% endcomment %}
{%- if property_images.size > 0 -%}
<div class="cm-customization-images">
{%- for item in property_images -%}
<div class="cm-customization-images-thumbnail {% if enable_image_modal %} cursor-pointer{% endif %}"
x-data="{
index: {{ forloop.index0 }},
propertyImages: '{{ property_orginal_images }}'
}"
@click="
previewIndex = index
imageArray = propertyImages.split(',')
if (imageArray.length > 1) {
if (index > 0 && index < imageArray.length - 1) {
showSlideLeftButton = true
showSlideRightButton = true
} else if (index === 0) {
showSlideLeftButton = false
showSlideRightButton = true
} else if (index === imageArray.length - 1) {
showSlideLeftButton = true
showSlideRightButton = false
}
}
currentImageUrl = imageArray[index]
openModal = true
">
{%- if enable_image_modal -%}
<div class="cm-customization-images-thumbnail-mask">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="white" class="cm-customization-images-thumbnail-svg">
<path d="M9 6a.75.75 0 0 1 .75.75v1.5h1.5a.75.75 0 0 1 0 1.5h-1.5v1.5a.75.75 0 0 1-1.5 0v-1.5h-1.5a.75.75 0 0 1 0-1.5h1.5v-1.5A.75.75 0 0 1 9 6Z" />
<path fill-rule="evenodd" d="M2 9a7 7 0 1 1 12.452 4.391l3.328 3.329a.75.75 0 1 1-1.06 1.06l-3.329-3.328A7 7 0 0 1 2 9Zm7-5.5a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11Z" clip-rule="evenodd" />
</svg>
</div>
{%- endif -%}
<img width="120" height="120" src="{{ item }}?x-oss-process=image/resize,s_{{ preview_image_width | times: 2 }}" />
</div>
{%- endfor -%}
</div>
{%- endif -%}
{% comment %} preview image modal {% endcomment %}
{%- if enable_image_modal -%}
<div class="cm-customization-modal"
x-show="openModal">
<div class="cm-customization-splide" role="group" aria-label="{{ title }}"
x-show="openModal"
x-transition:enter="cm-customization-transition"
x-transition:enter-start="cm-customization-modal-from"
x-transition:enter-end="cm-customization-modal-to"
x-transition:leave="cm-customization-transition"
x-transition:leave-start="cm-customization-modal-to"
x-transition:leave-end="cm-customization-modal-from">
<div class="cm-customization-splide-frame">
<img width="400" height="400" :src="currentImageUrl + '?x-oss-process=image/resize,l_960'">
<div x-show="showSlideLeftButton" class="cm-customization-splide-button cm-customization-splide-left"
@click="
previewIndex -= 1
currentImageUrl = imageArray[previewIndex]
if (imageArray.length > 1) {
if (previewIndex > 0 && previewIndex < imageArray.length - 1) {
showSlideLeftButton = true
showSlideRightButton = true
} else if (previewIndex === 0) {
showSlideLeftButton = false
showSlideRightButton = true
} else if (previewIndex === imageArray.length - 1) {
showSlideLeftButton = true
showSlideRightButton = false
}
}
">
<span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
<path fill-rule="evenodd" d="M14 8a.75.75 0 0 1-.75.75H4.56l3.22 3.22a.75.75 0 1 1-1.06 1.06l-4.5-4.5a.75.75 0 0 1 0-1.06l4.5-4.5a.75.75 0 0 1 1.06 1.06L4.56 7.25h8.69A.75.75 0 0 1 14 8Z" clip-rule="evenodd" />
</svg>
</span>
</div>
<div x-show="showSlideRightButton" class="cm-customization-splide-button cm-customization-splide-right"
@click="
previewIndex += 1
currentImageUrl = imageArray[previewIndex]
if (imageArray.length > 1) {
if (previewIndex > 0 && previewIndex < imageArray.length - 1) {
showSlideLeftButton = true
showSlideRightButton = true
} else if (previewIndex === 0) {
showSlideLeftButton = false
showSlideRightButton = true
} else if (previewIndex === imageArray.length - 1) {
showSlideLeftButton = true
showSlideRightButton = false
}
}
">
<span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
<path fill-rule="evenodd" d="M2 8a.75.75 0 0 1 .75-.75h8.69L8.22 4.03a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 0 1-1.06-1.06l3.22-3.22H2.75A.75.75 0 0 1 2 8Z" clip-rule="evenodd" />
</svg>
</span>
</div>
</div>
</div>
<div class="cm-customization-modal-close"
x-show="openModal"
x-transition:enter="cm-customization-transition"
x-transition:enter-start="cm-customization-close-from"
x-transition:enter-end="cm-customization-close-to"
x-transition:leave="cm-customization-transition"
x-transition:leave-start="cm-customization-close-to"
x-transition:leave-end="cm-customization-close-from"
@click="
openModal = false
">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="white">
<path d="M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z" />
</svg>
</div>
<div class="cm-customization-modal-bg"
x-show="openModal"
x-transition:enter="cm-customization-transition"
x-transition:enter-start="cm-customization-bg-from"
x-transition:enter-end="cm-customization-bg-to"
x-transition:leave="cm-customization-transition"
x-transition:leave-start="cm-customization-bg-to"
x-transition:leave-end="cm-customization-bg-from"
@click="
openModal = false
"><span></span></div>
</div>
{%- endif -%}
</div>
</div>
You can also download the “customeow-data.liquid” file to swap it out.
Save the file.
Find the “sections/main-cart-items.liquid” file.
Hit Command/Ctrl + F to pop open the file search window, then search for the `property in item.properties` code.
property in item.properties
Select the code, then hit Command/Ctrl + / to comment it out!
Copy the code for the rendering snippet.
{% comment %} CustoMeow Custom Data {% endcomment %}
{% render 'customeow-data',
properties: item.properties,
title: 'Your personalization',
preview_font_size: 12,
preview_image_width: 60,
preview_image_radius: 6,
enable_modal: true
%}
Paste the copied code right below the commented-out code.
Save the file.
Alright, let’s test it out now!
Exit the editor and head back to the theme, click the customize button to turn on the CustoMeow plugin.
After turning on the CustoMeow plugin, don’t forget to hit save!
Now preview this theme.
Find your customized product, tweak it, add it to the cart, and check out how it looks in the cart.
Cool! The cart’s now showing your customized data!
Advanced settings
We've got some settings you can tweak!
{% comment %} CustoMeow Custom Data {% endcomment %}
{% render 'customeow-data',
properties: item.properties,
title: 'Your personalization',
preview_font_size: 12,
preview_image_width: 60,
preview_image_radius: 6,
enable_modal: true,
cart_item_id: '',
cart_item_image_classname: ''
%}
Next up, let’s dive into what each setting does!
properties (required)
Grab the customization parameters for products in the cart—required field.
properties: item.properties,
title
Show the title for the customization section—optional.
title: 'Your personalization',
We suggest adding internationalized copy to make translation management a breeze.
{%- assign properties_title = 'general.cart.properie.title' | t -%}
{% render 'customeow-data',
properties: item.properties,
title: properties_title,
enable_modal: true
%}
enable_dark (optional)
If set to true, the text color will be forced to white, and the image style will be optimized for dark mode, default is false.
enable_dark: false,
text_color (optional)
Font text color, hex or rgba, default is 'oklch(37.3% .034 259.733)'
text_color: '#000000',
preview_font_size (optional)
Font size for users to preview customized text—optional, 12~16px, default is 12px.
preview_font_size: 12,
preview_image_width (optional)
Width of the preview image thumbnail—optional, default is 60px.
preview_image_width: 60,
preview_image_radius (optional)
Rounded corners for the preview image thumbnail—optional, default is 6px.
preview_image_radius: 6,
enable_modal (required)
Turn on or off the option to click the preview thumbnail to see the full-size image.
enable_modal: true,
modal_background_color (optional)
Set the background color for the image pop-up—when the image has transparent areas, you’ll see the background color shine through.
modal_background_color: '#000000',
The preview image shows up on the product image.
If you want the first preview image to show up on the product image, you’ll need to tweak these two settings!
cart_item_id (optional)
The cart’s item id—usually, the item’s sort order is used as the id.
You can find the cart item ID in the `main-cart-items.liquid` file.
<li id="CartItem-{{ item.index | plus: 1 }}">
<div>...</div>
</li>
cart_item_image_classname (optional)
The parent layer classname for the product image—if there isn’t one, you can just add your own classname.
// cart_item_image_classname => cart-item-thumbnail
{% comment %} product image {% endcomment %}
<div class="shrink-0 cart-item-thumbnail">
<img
src="{{ item.image | image_url: width: 300 }}"
class="cart-item__image size-16 rounded-md object-cover bg-gray-100 border border-gray-300 sm:size-40"
alt="{{ item.image.alt | escape }}"
loading="lazy"
width="150"
height="{{ 150 | divided_by: item.image.aspect_ratio | ceil }}">
</div>
Here's the final code, nice and ready.
{%- assign cart_item_index = item.index | plus: 1 -%}
{%- assign cart_item_id = 'CartItem-' | append: cart_item_index -%}
{% comment %} CustoMeow Custom Data {% endcomment %}
properties: item.properties,
title: 'Your personalization',
preview_font_size: 12,
preview_image_width: 60,
preview_image_radius: 6,
enable_modal: true,
modal_background_color: '#000000',
cart_item_id: cart_item_id,
cart_item_image_classname: 'cart-item-thumbnail'
%}
Save the code, head back to the cart, and let’s check out the results!