Security, Privacy, AI and CSR information for all Piano products now lives in one place. Explore our Compliance Center.
Audience
English French
English French

How to add Piano Content widget on AMP pages

Requirements

  • Piano Content widget created for mobile page

Instructions

The idea is an HTML page that renders only a Content widget and is loaded via an amp-iframe.

For example, the page should accept a widget ID and a context (URL) as query parameters.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
    // Async load of cx.js
    (function(d,s,e,t){e=d.createElement(s);e.type='text/java'+s;e.async='async';
    e.src='http'+('https:'===location.protocol?'s://s':'://')+'cdn.cxense.com/cx.js';
    t=d.getElementsByTagName(s)[0];t.parentNode.insertBefore(e,t);})(document,'script');
</script>
<style type="text/css">
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td {
  margin: 0;
  padding: 0;
}
</style>
</head>
<body>
<script type="text/javascript">
  var previousHeight = -1;
  var sendParentResizeMessage = function() {
    var height = previousHeight == -1 ? document.body.scrollHeight : document.body.offsetHeight;
    var message = {
      sentinel: 'amp',
      type: 'embed-size',
      height: height
    };
    if (previousHeight !== message.height) {
      previousHeight = message.height;
      window.parent.postMessage(message,"*");
    }
    setTimeout(sendParentResizeMessage, 250);
  };
  var getParameter = function(key) {
    var str = window.location.href.split("?");
    if (str.length < 2) {
      return "";
    }
    var params = str[1].split("&");
    for (var i = 0; i < params.length; i++) {
      var keyVal = params[i].split("=");
      if (keyVal[0] == key && keyVal.length == 2) {
        return decodeURIComponent(keyVal[1]);
      }
    }
    return "";
  };
</script>
<!-- Piano content widget -->
<div id="cx_widget_placeholder" style="display:none"></div>
<script type="text/javascript">
  var cX = cX || {}; cX.callQueue = cX.callQueue || [];
  cX.callQueue.push(['invoke', function() {
    var widgetId = getParameter("widgetId");
    var ctx = getParameter("ctx");
    cX.insertWidget({
      widgetId:widgetId, ctx: ctx,
      insertBeforeElementId: 'cx_widget_placeholder',
      width: '100%', height: 100, renderTemplateUrl: 'auto',
      onImpressionResult: sendParentResizeMessage
    });
  }]);
</script>
<!-- End of Piano content widget -->
</body>
</html>


On AMP pages, add an amp-iframe object referring to the HTML page:

[...]
  <script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
[...]


 <amp-iframe width=100 height=100
      sandbox="allow-top-navigation allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
      layout="responsive"
      frameborder="0"
      resizable
      src="https://cdn.cxpublic.com/amp-recs-template.html?widgetId=<widgetId>&ctx=<URL>">  <--- Make sure that the URL is encoded
    <div overflow tabindex=0 style="position:relative; padding-top:1.3em;">
      <a href="#" style="display:block;background-color:#eee; width:100%; height:30px; border: 1px solid #ddd; color: #174487; text-align:center; margin:0px 5px;">READ MORE</a>
    </div>
  </amp-iframe>

You can see a live demo here: https://onb-de1.cxense.com/public/samples/content/amp-sample.html

Tips & Warnings

  • There are important requirements you must follow to make amp-iframe work. Notably:

    • They must be either 600px from the top or outside the first 75% of the viewport when scrolled to the top—whichever is smaller.

    • They must request resources only via HTTPS, a data-URI, or the srcdoc attribute.

  • The 'overflow' element in the example above is illustrative; modify it to fit your page design.

Last updated: