Skip to main content
Tangiblee
 > 
Help Center

Semi-Managed

NOTE: Tangiblee does not recommend this option.

Based on our experience we would recommend Managed Integration due to the fact that Semi-Managed integration requires your development team to be responsible for ensuring Tangiblee’s functionality is compatible upon every new deployment and page layout change.

Through managed integration, Tangiblee runs QA and is responsible for ensuring that Tangiblee’s CTA and modal adhere to your ongoing changes and deployments. However, it is important to note that you should notify Tangiblee (success@tangiblee.com) if you have any ongoing product layout page or replatforming changes that we should be aware of. If not, we will only see that change on the page after it is deployed to production and the Tangiblee CTA will not appear until we update our mapping to reflect these changes.

With this option, the Tangiblee team develops the initial implementation of mapping code (aka tangiblee-mapper.js) tailoring Tangiblee to the PDP layout and structure of your website.

Semi-Managed integration consists of two code blocks:

  1. Mapping Code (tangiblee-mapper.js)
  2. Tangiblee API code (tangiblee.min.js)

Tangiblee recommends placing that tag in the same place where the other Javascript tags are added to the page - it may be the end of the <head> or <body> section. Tangiblee does not recommend GTM installation given the latest updates in IOS17.

Your IT team installs tangiblee-mapper.js either as a Tag or hosts it as a file and adds it directly to your website. Going forward, your IT has full control over the tangiblee-mapper.js to customize Tangiblee and when needed to update it according to changes in the PDP structure. More details about the possible customization of tangiblee-mapper.js can be found in the API Introduction article under the API Documentation section.

[.good]IMPORTANT: Before installing the tangiblee-mapper.js verify the SKU ID selector is correct and matches PDP structure - if there's a mismatch, update your account manager ASAP to fix that.[.good]

If you need to install Tangiblee on different environments with different configurations (e.g. STG, PRD) just duplicate the tangiblee-mapper.js and update it with the configuration changes. Below are two examples of tangiblee-mapper.js supporting different configurations. Also, more details around the possible customization of tangiblee-mapper.js can be found in the API Introduction article under the API Documentation section.

Single SKU (typical) - Semi-Managed Integration

Here is an example of Semi-Managed Integration: Typical Semi-Managed Sample PDP.

The tangiblee-mapper.js is similar to Managed Integration Sample PDP but is written by Tangiblee and hosted on the PDP directly instead of loading it from Tangiblee CDN.

[.good]Only generic Tangiblee API calls are made to the Tangiblee CDN which translates to saving a round trip to Tangiblee CDN to load the tangiblee-mapper.js.[.good]

Below is a sample code of a tangiblee-mapper.js with the following properties configured in the script:

  • Single SKU on the PDP
  • One active Locale
  • No Price/Currency/ATC in-popup
  • No Order Tracking
<!-- tangiblee-mapper.js code placed in a <script> tag -->
<script>
(function(){
    // helper function containing the code
    // that injects the demo CTA.
    // this code should be replaced with a
    // real CTA injecting for a given PDP     
    var showTangibleeCta = function(ctaThumbs) {
        var ctaClassName = 'tangiblee-shopify-cta',
            ctaContainer = document.getElementById('ProductThumbs'),
            cta = document.getElementsByClassName(ctaClassName)[0];
        if (cta) {
            cta.style.display = 'block';
        } else {
            if (ctaContainer) {
                var li = document.createElement('li');
                li.className = 'grid__item small--one-third medium-up--one-third';
                var btn = document.createElement('button');
                btn.className = 'product-single__thumbnail ' + ctaClassName;
                btn.style.border = '1px solid #333';
                btn.style.padding = '0';
                btn.style.margin = '0';
                btn.style.backgroundColor = '#fff';
                btn.style.width = '76px';
                btn.style.height = '76px';
                btn.style.fontSize = '1.4em';
                btn.style.fontWeight = 'bold';
                btn.style.lineHeight = '1.1em';
                btn.style.textAlign = 'center';
                btn.innerText = 'Will It Fit?';
                li.appendChild(btn);
                ctaContainer.appendChild(li);
            }          
        }
        return ctaClassName;
    };

    window.tangiblee = window.tangiblee ||
        function() {
            (tangiblee.q = tangiblee.q || []).push(arguments);
        };
    tangiblee('domain', 'www.tangiblee-integration.com');
    tangiblee('useCookies', true);
    tangiblee('showCTA', showTangibleeCta);
    tangiblee('startOnSKUs', ['2275915']);
})();
</script>

<!-- generic Tangiblee API - tangiblee.min.js - code placed in a <script> tag -->
<script async src="https://cdn.tangiblee.com/integration/3.1/tangiblee.min.js"></script>

[.bad]Please note: this is not your Integration Snippet, but an example for the sake of this guide. Your Tangiblee point of contact will share an Integration Snippet specifically for your website during the Onboarding Process.[.bad]

Multiple SKUs on PDP - Semi-Managed Integration

In this example, you can see a more complex tangiblee-mapper.js that handles a use-case of more than one SKU on the PDP. Also, more Tangiblee features are configured, such as Order Tracking.

For a full list of customization options and parameters you can use in tangiblee-mapper.js please see the API Introduction article under API Documentation section in the Knowledge Base.

Below is a sample code of a tangiblee-mapper.js with the following properties configured in the script:

  • Two SKUs on the PDP
  • One active Locale
  • Price/Currency/ATC in-popup
<!-- tangiblee-mapper.js code placed in a <script> tag -->
<script>
(function(){
    // helper function containing the code
    // that injects the demo CTA.
    // this code should be replaced with a
    // real CTA injecting for a given PDP      
    var showCta = function (ctaThumbs) {
       var ctaClassName = 'tangiblee-cta',
           cta = document.getElementsByClassName(ctaClassName)[0];
       if (!cta && window.thumbsCarousel) {
           var existingThumb = document.querySelector('.thumbsCarousel img');
           var wrapper = document.createElement('div');
           wrapper.style.position = 'relative';
           wrapper.style.width = existingThumb.width + 'px';
           wrapper.style.height = existingThumb.height + 'px';
           var btn = document.createElement('button');
           btn.style.position = 'absolute';
           btn.style.top = '50%';
           btn.style.left = '50%';
           btn.style.display = 'block';
           btn.style.margin = '-38px 0 0 -38px';
           btn.className = ctaClassName;
           btn.style.border = '1px solid #333';
           btn.style.padding = '0';
           btn.style.backgroundColor = '#fff';
           btn.style.width = '76px';
           btn.style.height = '76px';
           btn.style.fontSize = '1.4em';
           btn.style.fontWeight = 'bold';
           btn.style.lineHeight = '1.1em';
           btn.style.textAlign = 'center';
           btn.innerText = 'Will It Fit?';
           wrapper.appendChild(btn);
           window.thumbsCarousel.append(wrapper);
       }
       return ctaClassName;
   };

   // helper function containing the code
   // that hides the demo CTA.
   // this code should be replaced with a
   // real CTA hiding for a given PDP 
   var hideCTA = function (activeSKU) {
       var cta = document.getElementsByClassName('tangiblee-cta')[0];
       if (cta) {
           cta.parentNode.removeChild(cta);
       }
   };

   // helper function containing the code
   // that listens for the SKU change on the page and calls
   // tangiblee('activeSKU', activeSku);
   // when the value of active SKU is changed.
   // this code should be replaced with a
   // real SKU change detection for a given PDP 
   var skuChangingElement = document.getElementsByClassName('single-option-selector')[0];
   skuChangingElement.addEventListener('change', function () {
       var activeSku,
           selectedValue = document.getElementsByClassName('single-option-selector')[0].value;
       for (var i = 0; i < meta.product.variants.length; i = i + 1) {
           if (meta.product.variants[i].public_title === selectedValue) {
                   activeSku = meta.product.variants[i].sku;
                   break;
               }
       }
       if (activeSku) {
           tangiblee('activeSKU', activeSku);
       }
   });

   window.tangiblee = window.tangiblee || function () {
       (tangiblee.q = tangiblee.q || []).push(arguments);
   };
   tangiblee('domain', 'www.tangiblee-integration.com');
   tangiblee('activeLocale', 'en-US');
   tangiblee('useCookies', true);
   tangiblee('widgetVersion', 'v3');
   tangiblee('useEnhancedEcommerce', true);
   tangiblee('showCTA', showCta);
   tangiblee('hideCTA', hideCTA);
   tangiblee('activeCurrency', '$');
   tangiblee('activeATC', '.btn-cart');
   tangiblee('onSKUsValidated', function (atLeastOneSKUIsValid) {
       console.log('At least one SKU is valid: ' + JSON.stringify(atLeastOneSKUIsValid));
   });
   tangiblee('onCTAFirstShown', function () {
       console.log('Tangiblee CTA first shown!');
   });
   tangiblee('onCtaClicked', function () {
       console.log('Tangiblee CTA clicked!');
   });
   tangiblee('onModalOpened', function () {
       console.log('Tangiblee modal opened!');
   });
   tangiblee('onIframeLoaded', function () {
       console.log('Tangiblee iframe loaded!');
   });
   tangiblee('onModalClosed', function () {
       console.log('Tangiblee modal closed!');
   });
   tangiblee('activeSKU', 'F123356');
   tangiblee('startOnSKUs', ['F123356', 'F125170']);
   tangiblee('activePrice', '350');
})();
</script>

<!-- generic Tangiblee API - tangiblee.min.js - code placed in a <script> tag --> 
<script async src="https://cdn.tangiblee.com/integration/3.1/tangiblee.min.js"></script>

[.bad]Please note: this is not your Integration Snippet, but an example for the sake of this guide. Your Tangiblee point of contact will share an Integration Snippet specifically for your website during the Onboarding Process.[.bad]