Skip to content
  • There are no suggestions because the search field is empty.

Integrating Convert.com with Shopify Custom Storefronts and Cross-Origin Checkout

How to Track Conversions in Shopify Custom Storefronts and Cross-Origin Checkouts with Convert.com

IN THIS ARTICLE YOU WILL:

Overview

Convert.com’s Shopify App is built to work seamlessly with Liquid-based themes where the storefront and checkout page reside on the same domain.

However, if you're using a custom storefront (e.g., Shopify Hydrogen, WooCommerce) or if your checkout page is hosted on a different domain, you must manually configure tracking.

To enable Convert tracking in these advanced setups, follow the instructions below.

When is Manual Integration Required?

You need to manually integrate Convert’s tracking script if:
✔ You are using a custom storefront (e.g., Shopify Hydrogen, WooCommerce).
✔ Your Shopify checkout page is hosted on a different domain than the storefront.

In such cases, the following actions are necessary:

  • Install the Convert tracking script into the <head> tag of the storefront.

  • Use the helper function to generate cart attributes and update storage/cart manually.

Helper Function for Updating Cart Attributes

The following JavaScript function retrieves visitor data from Convert and formats it for Shopify’s cart attributes.

function getConvertCartAttribute({
   revenueGoalId,
   subscriptionGoalId, // optional
   oneTimePaymentGoalId, // optional
   currency
}) {
   if (typeof convert === 'undefined') return;
   const visitorData = convert.getAllVisitorData();
   const shopifyData = getShopifyData();
   if (!shopifyData) return;
   const attributes = {__data: shopifyData};
   for (const {experienceId, variationId} of visitorData.bucketing) attributes[`experience_${experienceId}`] = variationId;
   return attributes;

   function getShopifyData() {
      const experiences = visitorData.bucketing.filter(({experienceId}) => !!convert.data.experiences.find(({id, type}) => id === experienceId && type !== 'deploy')).map(({experienceId}) => String(experienceId));
      const domain = getCookieHost(convert.data.project.domains, location.hostname.replace(/^www\./, ''));
      return btoa(JSON.stringify({
         accountId: convert.data.account_id,
         projectId: convert.data.project.id,
         revenueGoalId,
         subscriptionGoalId,
         oneTimePaymentGoalId,
         visitorData,
         currency,
         experiences,
         domain,
      }));
   }

   function getCookieHost(domains, currentHost) {
      let cookieDomain;
      if (domains.find(({tld}) => tld === currentHost)) return (cookieDomain = `.${currentHost}`);
      for (const {tld, hosts} of domains) {
         if (hosts.find(host => host.includes(currentHost) || matchWildcard(currentHost, host))) {
            cookieDomain = `.${tld}`;
            break;
         }
      }
      return cookieDomain || false;
   }

   function matchWildcard(toMatch, wildcard) {
      return new RegExp(`^${wildcard.replace(/\./g, '\\.') .replace(/\?/g, '\\?').split('*').join('.*?')}$`).test(`www.${toMatch}`);
   }
}

Types Appendix: Shopify Data and Cart Attribute Format

// Storage Data
interface ShopifyData {
  accountId: string;
  projectId: string;
  revenueGoalId: string;
  subscriptionGoalId?: string;
  oneTimePaymentGoalId?: string;
  visitorData: VisitorData;
  currency: string;
  experiences?: string[];
  domain?: string;
}

// Cart Attributes
interface ConvertCartAttributes {
  __data: string;
  [key: string]: string;
}

 

Case 1: Custom Storefronts (Shopify Hydrogen, WooCommerce, etc.)

If you’re using a custom storefront, you must manually update Shopify’s storage data and cart attributes using the helper function.

Steps to Implement

  • Generate Convert Cart Attributes

const attributes = getConvertCartAttribute({
   revenueGoalId: 'xxxxxxxxx', // Replace with your revenue goal ID
   currency: 'xxx' // Replace with target currency (e.g., USD, EUR)
});

  • Update Shopify Storage Data
    This is required for tracking conversions related to Shopify standard events.

function updateShopifyStorageData(attributes) {
   const {__data: shopifyData} = attributes;
   if (!shopifyData) return;
   if (typeof convert === 'undefined') return;
   convert.setCookie('conv_shopify_data', shopifyData);
}
updateShopifyStorageData(attributes);
  • Update Shopify Cart Attributes (Optional) This is needed for the Shopify Order Webhook to work correctly.
function updateShopifyCartAttributes(attributes) {
   fetch(`${window?.Shopify?.routes || '/'}cart/update.js`, {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: btoa(JSON.stringify({attributes}))
   })
   .then(() => console.log("%cConvert: Cart attributes successfully updated", "color: lightgreen"))
   .catch(({message, stack}) => console.warn(`%cConvert: Cart attributes update error: ${message}`, "color: lightyellow"));
}
updateShopifyCartAttributes(attributes);

Case 2: Checkout Page on a Different Domain

If your checkout page is on a separate domain, you need to update Shopify Cart Permalinks to ensure tracking data is passed to the checkout process.

Steps to Implement

  1. Modify Cart Permalink URLs This script runs when the page loads and updates cart links dynamically.
(() => {
   if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', () => updateCartPermalinks());
   } else {
      updateCartPermalinks();
   }

   function updateCartPermalinks() {
      const attributes = getConvertCartAttribute({
         revenueGoalId: 'xxxxxxxxx', // Replace with your revenue goal ID
         currency: 'xxx' // Replace with target currency
      });
      if (!attributes) return;

      // Find cart links on the page and update their URLs
      const anchors = Array.from(document.querySelectorAll('a[href]')).filter(anchor => /\/cart\/\d+:\d+/.test(anchor.getAttribute('href')));
      anchors.forEach((link) => {
         const url = new URL(link.href, location.href);
         for (const key in attributes)
            if (!url.searchParams.has(key))
               url.searchParams.append(key, attributes[key]);
         link.href = url.toString();
      });
   }
})();

💡 Important Note:
Using cart permalinks means Convert can only track goals related to the checkout page. Goals such as collection_viewed, product_viewed, and search_submitted cannot be tracked.

 

If you're using a custom storefront or a cross-origin checkout, Convert tracking requires additional manual integration. By following the steps in this guide, you can ensure Convert continues to track conversion events correctly.

For further assistance, refer to our Shopify Support Articles.