police car

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.

Go to Credit Usage

pages
make shopify cart display custom content more effectively
Login
Get started free

Make Shopify’s Cart Display Custom Data More Effectively

Last updated: August 13, 2025
Starting today, if you’re subscribed to PRO or higher plan, we’ll tweak your cart code for free! Just hit up our online support or shoot support@customeow.io an email to get started.

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.

Download File

Save the file.

Shortcut Key: Save
Mac OS:
Command
+
S
Windows:
Ctrl
+
S

Find the “sections/main-cart-items.liquid” file.

The tutorial uses theme version 2.1. If your theme version doesn’t match, you can find and edit the cart-items.liquid file in the snippets folder.

Hit Command/Ctrl + F to pop open the file search window, then search for the `property in item.properties` code.

property in item.properties
Shortcut Key: Search
Mac OS:
Command
+
F
Windows:
Ctrl
+
F

Select the code, then hit Command/Ctrl + / to comment it out!

Shortcut Key: Comment code
Mac OS:
Command
+
/
Windows:
Ctrl
+
/

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.

Shortcut Key: Save
Mac OS:
Command
+
S
Windows:
Ctrl
+
S

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!

Alright, that’s it for now—see ya!