Shopify integration


We've partnered with UploadKit to bring you the best file uploading experience to Shopify. You can skip this entire guide by installing their plugin. Seamless workflow: use directly in Shopify admin. Free plan available. 7-day free trial.

Do it yourself

This guide covers adding customizable products to a Shopify store by integrating Uploadcare Uploading Widget, and implementing Uploading Widget API to allow product customizations. We'll also use image processing to render resized image previews of your customized Shopify products.

Shopify is an eCommerce platform that allows you to build online stores. However, you can add static item images only for your items. Uploadcare can help you create custom print sweatshirts, mugs with a logo, and other merchandise.

Specifically, we'll be building a product page for a customizable poster print:

Shopify product page

A user uploads an image of a future poster, and will see a product preview updated in real-time. We have added a condition that if the user hasn't selected an image, they will not be able to add the poster to the cart.

Let's get started.


Make a Shopify account

If you don't have one yet, create a Shopify account. This account is free for 14 days. We'll go with the Dawn theme, but you can pick anytheme you like. πŸ¦„

If you want to use Debut vintage theme, check here.

Create an Uploadcare account

Same here: if you aren't with us yet, sign up. Once you have an account, navigate to your dashboard to create a new Project, or discover API keys for an existing one. To go through the steps of this guide, you will need the Public API Key, which tells Uploadcare which project your file uploads should go to. The key can be found either in the API keys.

A screenshot of Uploadcare project dashboard

All files added by users will be stored in Uploadcare storage. You can view the files in the dashboard using the File tab.

Step 1. Setting up the product

Navigate to the Shopify admin panel to create your product. Go to the Products section and hit the Add product button. Fill out all the necessary fields such as product name, description, price, etc. Now, let's use Shopify's built-in uploader to upload a product image.

Click Add media from URL, and upload a poster template image from a URL, or you can upload a picture directly.

Note that the product image must have a transparent area, which will be β€œfilled” with the loaded image.

Shopify's product editor page

Fill in the inventory to add the item to the cart later. Also, make sure that Product Status is set to Active to appear in the store. Click Save to apply the changes.

Adding tags

Add a customizable tag to the Tags field. If the product doesn't have a customizable tag, the widget will not add to it. Click Save to apply the changes.

Disable the image zoom effect

You'll need to disable the image zoom effect for the uploaded product pictures to ensure that Shopify doesn't interfere with our upcoming image resize feature.

Shopify allows modifying themes, so let's hack some code. It's pretty simple: go to the Online store, hit Themes, choose your theme, hit Actions, and select Edit code in the dropdown menu.

First, we will hide the image zoom icon. To do that, discover product-thumbnail.liquid file through the search box and open it for editing.

Then find this line of code:

<span class="product__media-icon motion-reduce quick-add-hidden">{% render 'icon-play' %}</span>html

and comment it out using Shopify comment tags:

{% comment %}
  <span class="product__media-icon motion-reduce quick-add-hidden">{% render 'icon-play' %}</span>
{% endcomment %}html
Shopify's theme editor page

The second piece of code we need to comment out is:

  <span class="product__media-icon motion-reduce quick-add-hidden" aria-hidden="true">
    {%- liquid
      case media.media_type
      when 'video' or 'external_video'
        render 'icon-play'
      when 'model'
        render 'icon-3d-model'
        render 'icon-zoom'

We will use the same technique to do it:

{% comment %}
  <span class="product__media-icon motion-reduce quick-add-hidden" aria-hidden="true">
    {%- liquid
      case media.media_type
      when 'video' or 'external_video'
        render 'icon-play'
      when 'model'
        render 'icon-3d-model'
        render 'icon-zoom'
{% endcomment %}html

Don't forget to save the file by clicking the Save button in the top right-hand corner of the page.

When the zoom icon is hidden, let's disable the zoom feature by modifying the product-modal.js file a little bit.

Find the following line:

show(opener) {javascript

and add return false; after it this way:

show(opener) {
  return false;javascript

Disable cart notification

To simplify things, we will also disable the built-in cart notifications.

For that, go to the file editor again and find cart-notification.js file.

Search for this line:

open() {javascript

and add return false; after it:

open() {
  return false;javascript

We've just added a product to your shop, and prepared the theme!

πŸš€ Now, let's make our product customizable.

Step 2. Adding the Uploading Widget

Now, we'll need some prints to customize. Your users will upload the images, so we need to add the Uploading Widget by including the Uploadcare library.

Create a new file in the Snippets section. Name it uploadcare-settings.liquid, and add the uploader <script> element followed by another element containing your public API key:


Add another snippet named uploadcare-fields.liquid. We'll be adding an <input> element that will become the uploader button. Put the following lines in the snippet:

<p class="cart-attribute__field uploader-dawn">

As you see, our <input> comes with some attributes. Here's what they do:

  • data-images-only tells the Uploading Widget to accept images only.
  • data-crop defines the aspect ratio of the Uploading Widget image crop. Here we enable image cropping in the uploader with data-crop="5:7". In this case, 5:7 represents the ratio of the transparent area in the product image template. It may be different for your product.
  • name="properties[Upload]" link the Uploader with a custom property named Upload. As a result, a CDN URL of the uploaded file will be saved on Shopify's end and attached to the order. We'll access it from within the Cart and other pages.

Add the following lines to the theme.liquid file located in the Layout section right before the closing </head> tag:

{% if template == 'product' %} {% include 'uploadcare-settings' %} {% endif %}html

Look for the main-product.liquid file under the Sections category, find the following line:

{%- form 'product', product, id: product_form_id, class: 'form', novalidate: 'novalidate', data-type: 'add-to-cart-form' -%}html

This is a good place to add our upload field because it renders the add-to-card-form element. Put the following somewhere within it:

{% if product.tags contains 'customizable' %} {% include 'uploadcare-fields' %}
{% endif %}html

We're using the if statement to render the uploader only on products that have been tagged as customizable.

In this example, we decided to put the snippet right before the add-to-card button like in the screenshot below:

Shopify's code editor

There you go! You've just added the Uploading Widget to your product page. Users can now add their prints; our next step will show them a poster preview.

Step 3. Live product preview

We will add settings that will allow us to preview our product to be generated once an image has been uploaded. We can accomplish that using some JavaScript and the Uploading Widget API.

Create a new file in the Snippets section. Name it uploadcare-customizable-product.liquid, and add the <script>:

  // Get widget reference
  var widget = uploadcare.Widget("[role=uploadcare-uploader]");
  // Get product image element
  var productImage = document.querySelector(".product__media");
  // Get "buy now" button element
  var buyNowBtn = document.querySelector(".shopify-payment-button");
  // Get "add to cart" button element
  var addToCartBtn = document.querySelector(".product-form__submit");

  // Disable "add to cart" and "buy now" buttons
  buyNowBtn.disabled = true;
  addToCartBtn.disabled = true;

  // This fires once a file is uploaded
  widget.onUploadComplete(function (fileInfo) {
    // We take CDN URL of uploaded image and set it as CSS background
    // of the product image adjusting the position and size

    var uploadedImage = fileInfo.cdnUrl =
      "url(" + uploadedImage + "-/quality/smart/" + ")"; = "53% 50%"; = "48% 37%"; = "no-repeat";

    // Enable "add to cart" and "buy now" once image uploaded
    buyNowBtn.disabled = false;
    addToCartBtn.disabled = false;

Note that the class names of the elements in your theme may be different. Use developer tools to find the actual selectors in your theme. Also, the values of the backgroundSize and backgroundPosition parameters need to be adjusted to your product image and the actual position and size of the transparent area.

Add this snippet to main-product.liquid. It's better to place it at the bottom before the schema section:

{% if product.tags contains 'customizable' %} {% include
'uploadcare-customizable-product' %} {% endif %}html

Step 4. Preview in the cart

We stored CDN URLs of uploaded images in a dedicated property, and can render previews of customized products on the Cart page. In main-cart-items.liquid find the cart image container. In the Dawn theme it looks like this:

<div class="cart-item__image-container gradient global-media-settings">
  <img src="{{ item.image | image_url: width: 300 }}"
    alt="{{ item.image.alt | escape }}"
    height="{{ 150 | divided_by: item.image.aspect_ratio | ceil }}"

Replace it with the following lines:

<div class="cart-item__image-container gradient global-media-settings">
  <img src="{{ item.image | image_url: width: 300 }}"
      class="{% if != blank %}custom-product-preview{% endif %} cart-item__image"
      alt="{{ item.image.alt | escape }}"
      height="{{ 150 | divided_by: item.image.aspect_ratio | ceil }}"
      {% if != blank %}data-image-upload="{{ }}"{% endif %}

In addition to this change, we need to exclude the Upload property from display. For that, let's modify the if condition in this piece of code:

{%- for property in -%}
  {%- assign property_first_char = property.first | slice: 0 -%}
  {%- if property.last != blank and property_first_char != '_' -%}
      <div class="product-option">html

So the code looks like this:

{%- for property in -%}
  {%- assign property_first_char = property.first | slice: 0 -%}
  {%- if property.last != blank and property_first_char != '_' and property.first != 'Upload' -%}
      <div class="product-option">html

As a result, if there's a URL in the Upload property, Shopify will add it as a data attribute (data-image-upload) to the corresponding preview image. Also, it will add the custom-product-preview class to this image. To make use of this attribute, we need to add some JavaScript.

Create a new file in the Snippets section. Name the file uploadcare-cart-preview.liquid, and add the <script>:

  var previews = document.querySelectorAll(".custom-product-preview");
  previews.forEach(function (preview) {
    var background = preview.getAttribute("data-image-upload"); = "url(" + background + "-/quality/smart/" + ")"; = "53% 50%"; = "48% 37%"; = "no-repeat";

Then add the script to the botton of the main-cart-items.liquid template at (before the schema section):

{% include 'uploadcare-cart-preview' %}html

The script will take all images of the custom-product-preview class, and set the CDN URL from the data-image-upload attribute as a background β€” the same as we did on the product page.

You can also apply similar changes to Shopify email templates, for instance, to the order confirmation email (Store settings β†’ Notifications β†’ Order confirmation).


If everything is correct, your product page should now look like this:

Shopify Product Page

You should now see the uploaded image and custom product fields:

Shopify Cart Page


Yay! You have just created a customizable product. The flexibility of Uploadcare is now enhancing your Shopify store.

We're always here to help, as our friends from UploadKit with their plug-n-play solution.

If you have any questions, just post them in our community area.