Integrating Expivi via iFrame

Do you want to integrate Expivi, but do not wish to use an e-commerce platform such as Woocommerce or Shopify? Using an iFrame might be the solution. This page will describe how to integrate Expivi via iFrame.

1. Basic Setup

For basic usage of the viewer + options, the iFrame has very easy implementation. To start off, you’ll need two pages (it is not required to have the pages on the same domain, but due to security reasons it is highly recommended). Firstly, follow the Expivi viewer + Options integration document found on our knowledge website here.

Once this page has been setup, you’ll only need only 1 line of code in the second page:

<iframe src="https://www.example-website.com/expivi-viewer" id="myExpiviIframe" frameborder="0" width="100%" height="100%" allowfullscreen></iframe>

The iFrame will act as a window to the other page.

2. Communication between Expivi viewer and iFrame

Showing the viewer and/or options is easy to setup, but it understandable if you would like to have some communication in place between the viewer and the iFrame. For example, if the iFrame is used within a product page of a shop, you might want to save the product configuration within the product data once it is added to the cart.

The following implementation will attach a small script to the ‘add-to-cart’ button which will block the event temporarily. During this blockade, an event is being sent to the iFrame page requesting the product configuration. Once the configuration is ready, an event is sent back to the product page containing the configuration and the original event. The configuration will be attached to the event, followed by the event that removes its blockade, and continues the ‘add-to-cart’ action.

This setup might require some changes in how products are added to the cart as the ‘add-to-cart’ action will now provide Expivi product configuration data.

Implement the following code in the product page:

// Product page

// iFrame
<iframe src="iframe-page.php" id="myExpiviIframe" frameborder="0" width="100%" height="600" allowfullscreen></iframe>

// Add to cart button
<form action="#" method="post" class="cart">
    <button type="submit" name="add-to-cart">Add to cart</button>
</form>

// Scripts
<script type="text/javascript">
    var myIframe = document.querySelector('#myExpiviIframe');

    // Listen & catch/block 'add-to-cart' event
    document.addEventListener('submit', function (event) {
        // Check if the event is originated from 'add-to-cart' button
        if (event.target.classList.contains('cart')) {
            event.preventDefault();
            
            // Send 'add-to-cart' signal
            var data = { userData: event };
            var event = new CustomEvent('onAddToCart', { detail: data });
            myIframe.contentDocument.dispatchEvent(event);

            // Block event
            return false;
        }
    });

    // Listen to configuration event from iframe
    function onSaveConfiguration(e) {
        if (typeof e.detail !== 'undefined' && e.detail !== null && e.detail.error !== true) {
            try {
                var event = e.detail.userData;
                var configuration = JSON.parse(e.detail.data);
                var configuredProducts = configuration.configured_products;

                // Attach image to event
                var imageInput = document.createElement("input");
                imageInput.setAttribute("type", "hidden");
                imageInput.setAttribute("name", "image");
                imageInput.setAttribute("value", configuredProducts[0].thumbnail);
                delete configuredProducts[0].thumbnail;
                event.target.appendChild(imageInput);

                // Attach configuration to event
                var input = document.createElement("input");
                input.setAttribute("type", "hidden");
                input.setAttribute("name", "configuration");
                input.setAttribute("value", encodeURI(JSON.stringify(configuredProducts)));
                event.target.appendChild(input);
                
                // Submit event
                event.target.submit();
            } catch(ex) {
                console.error(ex);
            }
        }
    }
    window.document.addEventListener('configuration', onSaveConfiguration, false);
</script>

Implement the following code in the iFrame page:

// iFrame page
<script type="text/javascript">
  // Listen to 'add-to-cart' signal and send the configuration back to parent
  function onAddToCart(e) {
      window.expivi.saveConfiguration(256, 256).then(function(aConfiguration) {
          var data = { data: JSON.stringify(aConfiguration), userData: e.detail.userData, error: false };
          var event = new CustomEvent('configuration', { detail: data });
          window.parent.document.dispatchEvent(event);
      }, function(ex) {
          var event = new CustomEvent('configuration', { data: "", userData: e.detail.userData, error: true });
          window.parent.document.dispatchEvent(event);
      });
  }
  window.document.addEventListener('onAddToCart', onAddToCart, false);
</script>

3. Security

SameSite cookies

Since 4th of February 2020, chrome will block cookies coming from third-party websites by default. This means that cookies might be blocked between the product page and iFrame page/Expivi services (depending on if the iFrame page is setup on a different domain). It is recommend to check the SameSite setting on your server. Here is a website explaining the SameSite issue: https://web.dev/samesite-cookies-explained/

 

You have now successfully integrated Expivi as an iFrame!