CloudCart Integration

Updated on October 2, 2024

Go to shop and select custom CSS/JS

Add this code at the top of the page:

<script type="text/javascript" src="https://releva.ai/sdk/v0/js/releva-sdk-js.min.js"></script>

Add this code at the bottom of the page and change your access token and page tokens with the ones given to you by your account manager:

<!-- Releva Push -->
<script>
    // CONSTANTS: please change for each customer
    var accessToken = '';  // TODO: add your access token
    var homePageToken = ''; // TODO: add your home page token
    var categoryPageToken = '';  // TODO: add your category page token
    var productPageToken = ''; // TODO: add your product page token
    var cartPageToken = ''; // TODO: add your cart page token
    var searchPageToken = ''; // TODO: add your search page token
    var shopLocale = document.getElementsByTagName('html')[0].getAttribute('lang');
    var cartCurrencyString = 'лв';
    // END CONSTANTS
    var relevaPushOpts = {
      hasConsent: function() {
        var relevaConsentCookieValue = Releva.getCookie('cc-cookie-consent');
        var relevaHasConsent = relevaConsentCookieValue && relevaConsentCookieValue.indexOf('targeting') !== -1;
        if (!relevaHasConsent) {
          console.warn('Releva has not received targeting consent, running in cookiless mode.'); 
        }
        return relevaHasConsent;
      }
    };

    var categories = [];
    var customerObj = {};
    var productObj = {};
    window.relevaPushObject = {
      page: {
        locale: shopLocale,
        query: Releva.getUrlSearchParameterByName('query') || undefined
      }
    };
  
    var pageType = '';
    var cartProducts = [];
    console.log('Releva SDK loaded');

    //collect page data
    for (const e of dataLayer.entries()) {
      for (const obj of e) {
        if (!obj.cc_page_data) {
          continue
        }

        var pageData = obj.cc_page_data
        pageType = pageData.type

        if (pageData.products) {
          window.relevaPushObject.page.ids = [];
          for (var i = 0; i < pageData.products.length; i++) {
            window.relevaPushObject.page.ids.push(pageData.products[i].id.toString());
          }
        }

        if (pageType == 'category') {
          for (const category of pageData.breadcrumb) {
            categories.push(category.name)
          }
          window.relevaPushObject.page.categories = [categories.join('/')];
        }
        if (pageType == 'product') {
          window.relevaPushObject.product = {
            id: pageData.id.toString()
          }
        }

        if (pageType == 'checkout' || pageType == 'cart') {
          for (const product of pageData.products) {
            var tempPrice = product.price;
            if (product.discount_price > 0) {
              tempPrice = product.discount_price;
            }
            cartProducts.push({
              id: product.id.toString(),
              price: parseFloat(tempPrice.replace(/,/g, '.')),
              currency: product.currency,
              quantity: parseFloat(product.quantity),
            })
          }
          window.relevaPushObject.cart = {
            products: cartProducts
          }
        }
      }
    }
  
    var updateCart = function() {
      setTimeout(function() {
        var cartEl = document.getElementsByClassName('_cart-compact')
        var cartItems = cartEl[cartEl.length - 1].getElementsByTagName('li');
        var products = [];
        for (var i = 0; i < cartItems.length; i++) {
          var itemPriceElement = cartItems[i].getElementsByClassName('_cart-compact-products-list-item-price')[0];
          var itemPriceText = itemPriceElement.textContent;

          // Check if itemPriceText contains a valid price
          var priceMatch = itemPriceText.match(/\d+(\.\d+)?/);

          if (priceMatch) {
            var itemPrice = parseFloat(itemPriceText.split(' ')[0].replace(/,/g, '.'));

            var itemId = cartItems[i].getElementsByClassName('product-cart-product-image')[0].getAttribute('src').split('images/')[1].split('/')[0];
            var quantityElement = cartItems[i].querySelector('a._cart-compact-products-list-item-link > span._cart-compact-products-list-item-info > span._cart-compact-products-list-item-parameters.visible > span:nth-child(1) > span');
            var itemQuantityText = quantityElement.innerHTML;

            // Check if itemQuantityText contains a valid quantity
            var quantityMatch = itemQuantityText.match(/\d+/);

            if (quantityMatch) {
              var itemQuantity = parseFloat(quantityMatch[0]);

              products.push({
                id: itemId.toString(),
                price: itemPrice,
                quantity: itemQuantity,
              });
            }
          }
        }
        if (products.length > 0) {
          window.relevaPushObject.cart = {
            products: products
          }
        }
        //push for add to cart
        Releva.push(accessToken, window.relevaPushObject, function() {}, console.error, relevaPushOpts);
      }, 2000);
    };
  
    $(document).on('click', '.add-cart-product', function() {
	  // if ajaxModal is 'true', it means that a product dialog is open and we should track a product view instead
      // we do that in a different location
      if (!this.dataset.ajaxModal) {
        updateCart();
      }
    });
  
    $(document).on('submit', '.add-to-cart-form-js', function() {
	  updateCart();
    });
  
    //page push
    var pagePush = function() {
      if (pageType == 'category') {
        window.relevaPushObject.page.token = categoryPageToken;
      }
      if (pageType == 'home') {
        window.relevaPushObject.page.token = homePageToken;
      }
      if (pageType == 'search') {
        window.relevaPushObject.page.token = searchPageToken;
      }
      if (pageType == 'product') {
        window.relevaPushObject.page.token = productPageToken;
      }
      if (pageType == 'checkout' || pageType == 'cart') {
        window.relevaPushObject.page.token = cartPageToken;
        if (Object.keys(customerObj).length === 0) {
          $('.cc-form-shipping-type').on("submit", function() {
            var queryString = $('.cc-form-shipping-type').serializeArray();
            $.each(queryString, function(index, fieldValuePair) {
              if (fieldValuePair.name == 'email') {
                customerObj['email'] = fieldValuePair.value;
              }
              if (fieldValuePair.name == 'checkout[shipping][address][first_name]') {
                customerObj['firstName'] = fieldValuePair.value;
              }
              if (fieldValuePair.name == 'checkout[shipping][address][last_name]') {
                customerObj['lastName'] = fieldValuePair.value;
              }
              if (fieldValuePair.name == 'checkout[shipping][address][phone]') {
                customerObj['phoneNumber'] = fieldValuePair.value;
              }
            });
            window.relevaPushObject.profile = customerObj;
            //push for cart guest checkout
            Releva.push(accessToken, window.relevaPushObject, function() {}, console.error, relevaPushOpts);
          });
        }
      }
      
      if(document.getElementsByClassName('page-product').length > 0 && document.getElementsByClassName('modal-dialog product-details').length > 0){
		delete window.relevaPushObject.page.token;
      }

      Releva.push(accessToken, window.relevaPushObject, function() {}, console.error, relevaPushOpts);
    }

    //collect customer data
    var originalPush = dataLayer.push
    dataLayer.push = function(...args) {
      originalPush.apply(dataLayer, args);
      for (const arg of args) {
        if (arg.cc_customer_data) {
          var customer = arg.cc_customer_data;
          window.relevaPushObject.profile = {
            firstName: customer.first_name,
            lastName: customer.last_name,
            email: customer.email
          }
        }
        // we need this for popup product view push
        if (arg.cc_page_data) {
			    pageType = 'product';
			    window.relevaPushObject.product = {
			  	  id: arg.cc_page_data.id.toString()
			    }
          pagePush();
          // clean up so we don't keep attributing to recommender forever
          delete window.relevaPushObject.rid;
          delete window.relevaPushObject.rpid;
        }
      }
    }
  
    $(document).on('click','._cart-compact-button',function() {
 	      window.relevaPushObject.page.token = cartPageToken;
        Releva.push(accessToken, window.relevaPushObject, function() {}, console.error, relevaPushOpts);
    })
  
    document.addEventListener('click', function(e) {
      var target = e.target;
      if (target.getAttribute('data-modal-class') !== 'product-details') {
        target = e.target.closest('[data-modal-class="product-details"]');
      }
      if (target && target.href && window.relevaPushObject) {
        var searchParams = new URL(target.href).searchParams;
        window.relevaPushObject.rid = searchParams.get('rlv_rid');
        window.relevaPushObject.rpid = searchParams.get('rlv_rpid');
      }
    });
  
    window.addEventListener('load', function () {
      pagePush();
    });
</script>
<!-- /Releva Push -->