Code Integration BigCommerce

Overview

In this guide we will be cloning your live theme for code editing, locating the Subtotal Container on your Cart page, which will house the Shipping Protection Offer Element. Once identified both on page and in your Cart page's code you will then added in the code required to populate the Shipping Offer onto the Cart's page.

Estimated time of completion: 1 Hour

Configuration

🚧

Follow this guide to setup and run your theme locally using Stencil here


Shipping Protection Snippet

Locate checkout.html

Commonly found in templates/pages

Paste the following snippet at the very bottom of your checkout.html file

<!-- Extend script tags - these can be moved into script manager to apply only to product and cart pages -->
<script src="https://sdk.helloextend.com/extend-sdk-client/v1/extend-sdk-client.min.js"></script>
<script src="https://sdk.helloextend.com/extend-sdk-client-bigcommerce-addon/v1/extend-sdk-client-bigcommerce-addon.min.js"></script>
<script>Extend.config({ storeId: 'Your Extend StoreId' })</script>
<!-- Extend script tags end -->

<!-- Extend - checkout SP offers -->
<script>
  'use strict';
  function renderShippingProtectionOffer(spCart) {
    ExtendBigCommerce.getCart((_, cart) => {
      const itemsMapped = ExtendBigCommerce.formatCartItemsForSp(spCart);
      if (Extend.shippingProtection._instance !== null) {
        Extend.shippingProtection.update({ items: itemsMapped });
      } else {
        Extend.shippingProtection.render({
          selector: "#extend-shipping-offer",
          items: itemsMapped,
          isShippingProtectionInCart:
            ExtendBigCommerce.isShippingProtectionInCart(spCart),
          onEnable: function (quote) {
            const callback = (err) => {
              if (err) {
                console.log(err);
                return;
              } else {
                window.location.reload();
              }
            };
            return ExtendBigCommerce.addSpPlanToCart(
              { quote, cart: spCart },
              callback
            );
          },
          onDisable: function (quote) {
            const callback = (err, res) => {
              if (err) {
                console.log(err);
                return;
              } else {
                window.location.reload();
              }
            };
            return ExtendBigCommerce.removeSpPlanFromCart(
              { quote, cart: spCart },
              callback
            );
          },
          onUpdate: function (quote) {
            const callback = (err, data) => {
              if (err) {
                console.log(err);
                return;
              } else if (data.spPlanUpdated) {
                window.location.reload();
              }
            };
            return ExtendBigCommerce.getCart((error, cart) => {
              ExtendBigCommerce.updateSpPlanInCart({ quote, cart }, callback);
            });
          },
        });
      }
    });
  }

  

  var listeners = [],
  doc = window.document,
  MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
  observer;

  function ready(selector, fn) {
  // Store the selector and callback to be monitored
      listeners.push({
          selector: selector,
          fn: fn
      });
      if (!observer) {
  // Watch for changes in the document
          observer = new MutationObserver(check);
          observer.observe(doc.documentElement, {
              childList: true,
              subtree: true
          });
      }
  // Check if the element is currently in the DOM
      check();
  }

  function check() {
  // Check the DOM for elements matching a stored selector
      for (var i = 0, len = listeners.length, listener, elements; i < len; i++) {
          listener = listeners[i];
          // Query for elements matching the specified selector
          elements = doc.querySelectorAll(listener.selector);
          for (var j = 0, jLen = elements.length, element; j < jLen; j++) {
              element = elements[j];
              // Make sure the callback isn't invoked with the
              // same element more than once
              if (!element.ready) {
                  element.ready = true;
                  // Invoke the callback with the element
                  listener.fn.call(element, element);
              }
          }
      }
  }

  window.addEventListener("load", () => {
    if (window.Extend && window.ExtendBigCommerce) {
      /**********************/
      /*  Global Variables  */
      /**********************/
      const shippingProtectionOfferId = "extend-shipping-offer"; // This is the ID that will be assigned to the Extend Shipping Protection Offer
      const shippingProtectionContainer = ".cart-section.optimizedCheckout-orderSummary-cartSection"; // This is where the checkout shipping protection offer will be APPENDED (Switch to prepend or insertBefore as needed)

      // Create shipping protection empty div
      const shippingProtectionOffer = document.createElement("div");
      shippingProtectionOffer.id = shippingProtectionOfferId;
      shippingProtectionOffer.style.marginTop = "50px";
      shippingProtectionOffer.style.marginBottom = "-50px";

      // Get's updated cart object
      ExtendBigCommerce.getCart(function (error, cart) {
        if (cart) {
          // Run normalization and handle shipping protection
          ExtendBigCommerce.updateExtendLineItems(
            { balanceCart: true },
            function (err, data) {
              if (data && (data.updates || data.additions)) {
                  window.location.reload();
              }
              let productList = '.productList'
              ready(productList, () => {
                let shippingProtectionSelector = document.querySelector(shippingProtectionContainer);
                shippingProtectionSelector.append(shippingProtectionOffer);
                renderShippingProtectionOffer(data.cart);

                var products = document.querySelectorAll(".product");
                var warrantyProducts = Array.from(products).filter((item) => {
                  var productTitle = item.querySelector(".product-title").textContent;
                  if (
                    productTitle.includes("Extend Protection") ||
                    productTitle.includes("Extend Shipping")
                  ) {
                    item.querySelector(
                      ".product-figure"
                    ).innerHTML = `<img alt="${productTitle}" data-test="cart-item-image" src="{{cdn 'img/extend_logo.png'}}">`;
                    return item;
                  }
                });
              })
            }
          );
        }
      });
    }
  });
</script>
<!-- Extend - End Extend Code -->

Configure Extend storeID

At the top of the snippet you pasted in, ensure you update your Extend StoreID!


Configure Extend Shipping Protection Offer Placement

  • On the cart page, right click on the summary box and click “Inspect element”
  • Find the element that contains the cart-section element
  • Copy the class name

  • In the snippet you pasted, near the top of the 'load' event, set this to the class or selector of where you would like the Extend Shipping Protection offer appended.


Replace Old Extend Normalization

Locate extend.js

commonly found in assets/js/theme

  • a. Inside of extend.js find the code block below:
// Run normalization
ExtendBigCommerce.normalizeCart({ cart: cart, balance: true }, function (err, data) {
  if (data && data.updates) {
    if(Extend.analytics){
      return window.dispatchEvent(new CustomEvent('normalization', {detail: {updates: data.updates}}))
    } else {
      window.location.reload();
    }
  }
});
  • b. cut and replace it with the snippet below:
// Run normalization - supports product protection and shipping protection
ExtendBigCommerce.updateExtendLineItems({ balanceCart: true }, function (err, data) {
  if (data && (data.updates || data.additions)) {
    if(Extend.analytics){
      return window.dispatchEvent(new CustomEvent('normalization', {detail: {updates: data.updates}}))
    } else {
      window.location.reload();
    }
  }
});


Hide Shipping Protection Line Item

Now we will add some additional code to ensure that the Shipping Protection Line Item is hidden on the preview cart and main cart pages. This is meant to clean up the Cart page experience overall.


Locate content.html

  • Navigate to templates/components/cart/content.html

Edit

  • Find where the code is looping through each cart item and at the top of the loop add the following snippet:
<!-- Extend Hide SP Items -->
{{#if name '!==' 'Extend Shipping Protection Plan'}}

  • Scroll down to the bottom of the file and find where the loop is ending, add the following snippet below:
{{/if}}
  <!-- Extend - End code -->

Great job, you have implemented the code pieces needed to facilitate Shipping Protection Offers on your BigCommerce Store. Next we will go over some Verification steps needed to complete the project.

If you run into any issues during this integration process or have questions please reach out to our team through your Merchant Portal.


Checklist