Steps for Setting Up WIREWAX add to cart with Shopify Cart

Shopify-logo

important

Please contact our team at support@wirewax.com to ensure this feature is available and properly setup for your ENTERPRISE account.

Connecting WIREWAX add-to-cart API with Shopify Cart will require JavaScript program skill. The following tutorial is to provide an minimal example of a functional Shoppable video on Shopify store.

You might need to check the following links for further references:

In this tutorial we will create an example to add a single product (variant id: 37971713982656) to Shopify Cart through clicking a WIREWAX video hotspot.

1. Prepare interactive video and Product id#

Find the id of the product variant you want to configure into a shoppable experience, following this tutorial.

note

Currently Shopify only supports add a product to cart through variant id. SKU is not supported by Shopify Cart API.

In WIREWAX Studio, choose the hotspot you want to associate with this variant, change the Hotspot Action to "do nothing" and add the id in Custom Reference Field.

shopify-example-1

2. Add WIREWAX iframe API script to Shopify Theme#

  1. Login Shopify Store Admin: YOUR_STORE.myshopify.com/admin
  2. Go to Themes and choose Customize theme to open theme UI editor
  3. Go to Theme actions and choose Edit Code to open theme code editor
  4. In Layout/theme.liquid file, append the following wirewax iframe script to the end of head tag
    <head>
    <!-- ... -->
    <script type="text/javascript" src="//iframe.wirewax.com/wirewax-api.min.js"></script>
    </head>

3. Add a WIREWAX video to your page#

WIREWAX video can be added to a Shopify site wherever a Custom content/Custom HTML block (in theme template) or Edit as HTML(in posts, pages) are allowed.

We will use theme template (for home page) as an example.

  1. Add a Custom content block
  2. Inside Custom content block, choose Add content, and in dropdown, choose Custom HTML
  3. Copy/Paste embed code from WIRWAX Studio Embed tab into the custom HTML block
    <div style="
    position: relative;
    width: 100%;
    height: 0;
    padding-bottom: 56.25%;">
    <iframe style="position: absolute; top: 0; left: 0;" width="100%" height="100%" src="https://embedder.wirewax.com/8175508/" frameborder="0" scrolling="yes" allowfullscreen="" id="wirewax-player"></iframe>
    </div>
  4. Video should be shown immediately.

4. Connecting WIREWAX API with Shopify Ajax API and product variant id#

In above steps, we have setup WIREWAX video and WIREWAX iframe API to emit WIREWAX video events to Shopify, in this step, we will:

  1. Create a function AddToShopifyCart to use Shopify Ajax API to add a product variant to Shopify Cart
  2. Add EventListener to monitor WIREWAX video interactivity, and use AddToShopifyCart as event handler callback
  3. Add these functions to WIREWAX video Custom HTML block

AddToShopifyCart - Use Shopify Ajax API#

In the following example, we created a function called addToShopifyCart, it takes formData and will add the item describe in formData to Shopify Cart. In the following example, quantity is the amount of the variant that you want to add and id is the variant ID of that variant. You can add multiple variants to the cart by appending more objects in the items array.

// A basic usage off Shopify Ajax Cart API
let formDataExample = {
items: [
{
id: 37971713982656,
quantity: 1
}
]
}
window.wirewax.addToShopifyCart = function (formData) {
fetch("/cart/add.js", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(formData)
})
.then((response) => {
return response.json();
})
.then((json) => {
// This part will be covered in Advanced setup
// window.wirewax.setupShopifyCartPopup(json.items[0]);
})
.catch((error) => {
console.error("Error:", error);
});
};

Listening to WIREWAX events - Use WIREWAX iframe API#

In the following example, we are listening to a WIREWAX hotspot click event. The handler function will receive a data object. Inside the handler function, we check if this hotspot is configured to product variant 37971713982656, and call the addToShopifyCart method we just created.

const productId = "37971713982656";
window.wirewax.addEventListener(
window.wirewax.events.listeners.TAG_CLICK,
function (data) {
console.log("WIREWAX hotspot is clicked:", { data });
if (
data.data.tagData.customNameRef === productId ||
data.data === productId
) {
window.wirewax.addToShopifyCart({
items: [{ id: productId, quantity: 1}]
});
}
}
);

Add functions to Custom HTML block#

Open the Custom HTML Block we that has WIREWAX video embed. Add a HTML script tag, copy/paste into these two functions:

<!-- In Custom HTML Block -->
<div style="
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%;
">
<iframe style="position: absolute; top: 0; left: 0;" width="100%" height="100%" src="https://embedder.wirewax.com/8175508/" frameborder="0" scrolling="yes" allowfullscreen="" id="wirewax-player">
</iframe>
</div>
<!-- This is the final result -->
<script>
window.wirewax.addToShopifyCart = function (formData) {
fetch("/cart/add.js", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(formData)
})
.then((response) => {
return response.json();
})
.then((json) => {
// This part will be covered in Advanced setup
// window.wirewax.setupShopifyCartPopup(json.items[0]);
})
.catch((error) => {
console.error("Error:", error);
});
};
const productId = "37971713982656";
window.wirewax.addEventListener(
window.wirewax.events.listeners.TAG_CLICK,
function (data) {
console.log("WIREWAX hotspot is clicked:", { data });
if (
data.data.tagData.customNameRef === productId ||
data.data === productId
) {
window.wirewax.addToShopifyCart({
items: [{ id: productId, quantity: 1}]
});
}
}
);
</script>
tip

You can wrap the code snippet into a js file and link it here:

<!-- In Custom HTML Block -->
<div style="
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%;
">
<iframe style="position: absolute; top: 0; left: 0;" width="100%" height="100%" src="https://embedder.wirewax.com/8175508/" frameborder="0" scrolling="yes" allowfullscreen="" id="wirewax-player">
</iframe>
</div>
<!-- This is the final result-->
<script src="https://edge-assets.wirewax.com/creativeData/shopify/shopify-example.js"></script>

5.Shopify Cart Advanced Setup#

With the above two snippets, we finished a minimal workflow to add a product from WIREWAX video directly to Shopify Cart. However, this workflow won't pop up Shopify cart popup. We recommend to add some advanced setup to enable a smoother experience.

note

This advanced step is beyond minimal functionality and most likely will change depending on the Shopify theme and custom cart configuration. The follow snippet is created based on "Debut" theme with default Shopify Cart setup. Adding the snippet will enable Cart Popup on "Debut" theme.

Full example script can be find here: https://edge-assets.wirewax.com/creativeData/shopify/shopify-example.js

// 1. Add Shopify selectors
window.wirewax.shopifySelectors = {
addToCart: "[data-add-to-cart]",
addToCartText: "[data-add-to-cart-text]",
cartCount: "[data-cart-count]",
cartCountBubble: "[data-cart-count-bubble]",
cartPopup: "[data-cart-popup]",
cartPopupCartQuantity: "[data-cart-popup-cart-quantity]",
cartPopupClose: "[data-cart-popup-close]",
cartPopupDismiss: "[data-cart-popup-dismiss]",
cartPopupImage: "[data-cart-popup-image]",
cartPopupImageWrapper: "[data-cart-popup-image-wrapper]",
cartPopupImagePlaceholder: "[data-image-loading-animation]",
cartPopupProductDetails: "[data-cart-popup-product-details]",
cartPopupQuantity: "[data-cart-popup-quantity]",
cartPopupQuantityLabel: "[data-cart-popup-quantity-label]",
cartPopupTitle: "[data-cart-popup-title]",
cartPopupWrapper: "[data-cart-popup-wrapper]",
loader: "[data-loader]",
loaderStatus: "[data-loader-status]",
quantity: "[data-quantity-input]",
SKU: ".variant-sku",
productStatus: "[data-product-status]",
// originalSelectorId: "#ProductSelect-" + sectionId,
productForm: "[data-product-form]",
errorMessage: "[data-error-message]",
errorMessageWrapper: "[data-error-message-wrapper]",
imageZoomWrapper: "[data-image-zoom-wrapper]",
productMediaWrapper: "[data-product-single-media-wrapper]",
// productThumbImages: ".product-single__thumbnail--" + sectionId,
// productThumbs: ".product-single__thumbnails-" + sectionId,
productThumbListItem: ".product-single__thumbnails-item",
productThumbsWrapper: ".thumbnails-wrapper",
// saleLabel: ".product-price__sale-label-" + sectionId,
// singleOptionSelector: ".single-option-selector-" + sectionId,
shopifyPaymentButton: ".shopify-payment-button",
productMediaTypeVideo: "[data-product-media-type-video]",
productMediaTypeModel: "[data-product-media-type-model]",
priceContainer: "[data-price]",
regularPrice: "[data-regular-price]",
salePrice: "[data-sale-price]",
unitPrice: "[data-unit-price]",
unitPriceBaseUnit: "[data-unit-price-base-unit]",
productPolicies: "[data-product-policies]",
storeAvailabilityContainer: "[data-store-availability-container]"
};
// 2. Add shopify classes
window.wirewax.shopifyClasses = {
cartPopupWrapperHidden: "cart-popup-wrapper--hidden",
hidden: "hide",
visibilityHidden: "visibility-hidden",
inputError: "input--error",
jsZoomEnabled: "js-zoom-enabled",
productOnSale: "price--on-sale",
productUnitAvailable: "price--unit-available",
productUnavailable: "price--unavailable",
productSoldOut: "price--sold-out",
cartImage: "cart-popup-item__image",
productFormErrorMessageWrapperHidden: "product-form__error-message-wrapper--hidden",
activeClass: "active-thumb",
variantSoldOut: "product-form--variant-sold-out"
};
window.wirewax.setupShopifyCartPopup = function(item) {
window.wirewax.cartPopup = document.querySelector(
window.wirewax.shopifySelectors.cartPopup
);
window.wirewax.cartPopupWrapper = document.querySelector(
window.wirewax.shopifySelectors.cartPopupWrapper
);
window.wirewax.cartPopupTitle = document.querySelector(
window.wirewax.shopifySelectors.cartPopupTitle
);
window.wirewax.cartPopupQuantity = document.querySelector(
window.wirewax.shopifySelectors.cartPopupQuantity
);
window.wirewax.cartPopupQuantityLabel = document.querySelector(
window.wirewax.shopifySelectors.cartPopupQuantityLabel
);
window.wirewax.cartPopupClose = document.querySelector(
window.wirewax.shopifySelectors.cartPopupClose
);
window.wirewax.cartPopupDismiss = document.querySelector(
window.wirewax.shopifySelectors.cartPopupDismiss
);
window.wirewax.cartPopupImagePlaceholder = document.querySelector(
window.wirewax.shopifySelectors.cartPopupImagePlaceholder
);
window.wirewax.setupCartPopupEventListeners();
window.wirewax.updateCartInfo(item);
};
window.wirewax.setupCartPopupEventListeners = function() {
window.wirewax.shopifyHideCart = function() {
window.theme.Helpers.prepareTransition(
window.wirewax.cartPopupWrapper
);
window.wirewax.cartPopupWrapper.classList.add(
window.wirewax.shopifyClasses.cartPopupWrapperHidden
);
var cartPopupImage = document.querySelector(
window.wirewax.shopifySelectors.cartPopupImage
);
if (cartPopupImage) {
cartPopupImage.remove();
}
window.wirewax.cartPopupImagePlaceholder.setAttribute(
"data-image-loading-animation",
""
);
};
window.wirewax.cartPopupClose.addEventListener(
"click",
window.wirewax.shopifyHideCart
);
window.wirewax.cartPopupDismiss.addEventListener(
"click",
window.wirewax.shopifyHideCart
);
};
window.wirewax.updateCartInfo = function(item) {
var quantity = 1;
var selling_plan_name = item.selling_plan_allocation ?
item.selling_plan_allocation.selling_plan.name :
null;
window.wirewax.cartPopupTitle.textContent = item.product_title;
window.wirewax.cartPopupQuantity.textContent = quantity;
window.wirewax.cartPopupQuantityLabel.textContent = window.theme.strings.quantityLabel.replace(
"[count]",
quantity
);
window.wirewax._setCartPopupPlaceholder(item.featured_image.url);
window.wirewax._setCartPopupImage(
item.featured_image.url,
item.featured_image.alt
);
fetch("/cart.js", {
credentials: "same-origin"
})
.then(function(response) {
return response.json();
})
.then(function(cart) {
window.wirewax._setCartQuantity(cart.item_count);
window.wirewax.updateShopifyCountBubble(cart.item_count);
window.wirewax.showShopifyCart();
})
.catch(function(error) {
// eslint-disable-next-line no-console
console.log(error);
});
};
window.wirewax._setCartQuantity = function(quantity) {
window.wirewax.cartPopupCartQuantity =
window.wirewax.cartPopupCartQuantity ||
document.querySelector(window.wirewax.shopifySelectors.cartPopupCartQuantity);
var ariaLabel;
if (quantity === 1) {
ariaLabel = window.theme.strings.oneCartCount;
} else if (quantity > 1) {
ariaLabel = window.theme.strings.otherCartCount.replace("[count]", quantity);
}
window.wirewax.cartPopupCartQuantity.textContent = quantity;
window.wirewax.cartPopupCartQuantity.setAttribute("aria-label", ariaLabel);
};
window.wirewax._setCartPopupPlaceholder = function(imageUrl) {
window.wirewax.cartPopupImageWrapper =
window.wirewax.cartPopupImageWrapper ||
document.querySelector(
window.wirewax.shopifySelectors.cartPopupImageWrapper
);
if (imageUrl === null) {
window.wirewax.cartPopupImageWrapper.classList.add(
window.wirewax.shopifyClasses.hidden
);
return;
}
};
window.wirewax._setCartPopupImage = function(imageUrl, imageAlt) {
if (imageUrl === null) return;
window.wirewax.cartPopupImageWrapper.classList.remove(
window.wirewax.shopifyClasses.hidden
);
var sizedImageUrl = window.theme.Images.getSizedImageUrl(
imageUrl,
"200x"
);
var image = document.createElement("img");
image.src = sizedImageUrl;
image.alt = imageAlt;
image.classList.add(window.wirewax.shopifyClasses.cartImage);
image.setAttribute("data-cart-popup-image", "");
image.onload = function() {
window.wirewax.cartPopupImagePlaceholder.removeAttribute(
"data-image-loading-animation"
);
window.wirewax.cartPopupImageWrapper.append(image);
}.bind(this);
};
window.wirewax._setCartPopupProductDetails = function(
product_has_only_default_variant,
options,
properties,
selling_plan_name
) {
window.wirewax.cartPopupProductDetails = document.querySelector(
window.wirewax.shopifySelectors.cartPopupProductDetails
);
var variantPropertiesHTML = "";
if (!product_has_only_default_variant) {
variantPropertiesHTML =
variantPropertiesHTML + this._getVariantOptionList(options);
}
if (selling_plan_name) {
variantPropertiesHTML =
variantPropertiesHTML + this._getSellingPlanHTML(selling_plan_name);
}
if (properties !== null && Object.keys(properties).length !== 0) {
variantPropertiesHTML =
variantPropertiesHTML + this._getPropertyList(properties);
}
if (variantPropertiesHTML.length === 0) {
this.cartPopupProductDetails.innerHTML = "";
this.cartPopupProductDetails.setAttribute("hidden", "");
} else {
this.cartPopupProductDetails.innerHTML = variantPropertiesHTML;
this.cartPopupProductDetails.removeAttribute("hidden");
}
};
window.wirewax.updateShopifyCountBubble = function(quantity) {
const cartCountBubble = document.querySelector(
window.wirewax.shopifySelectors.cartCountBubble
);
const cartCount = document.querySelector(
window.wirewax.shopifySelectors.cartCount
);
cartCountBubble.classList.remove(window.wirewax.shopifyClasses.hidden);
cartCount.textContent = quantity;
};
window.wirewax.showShopifyCart = function() {
window.theme.Helpers.prepareTransition(window.wirewax.cartPopupWrapper);
window.wirewax.cartPopupWrapper.classList.remove(
window.wirewax.shopifyClasses.cartPopupWrapperHidden
);
};