Most of the everyday emails you may get as a consumer are the same. They’re mostly static information that won’t let you interact, and will send you to a website to do so. By implementing Accelerated Mobile Pages (AMP) in your emails, you can change this for your customers. This blog post will introduce you to the basics of AMP and how to implement data-driven, interactive email experiences in Marketing Cloud.
AMP
AMP, in a nutshell, is a web component framework designed for mobile B2C end-user experiences. It was developed by Google and is now part of the OpenJS foundation. At this point, it’s more than likely that you have experienced AMP from the user-land perspective. For example, when you search Google for your favorite location or newspaper, you might experience AMP. The following screenshot shows such a search result. The lightning symbol in the top right corner indicates that this content is served via AMP.
You can learn more about AMP in general, as well as its usage scenarios on the AMP project site. For this blog post though, we’ll look at the ability to use AMP, and here the subset AMP Email, within your Marketing Cloud emails.
Interactive emails with AMP
Let’s take a look at an interactive email example in the following GIF. Envision that you ordered a new bike, and received the usual confirmation email. With AMP components, this email is no longer static. The email provides an interactive experience for scheduling a setup appointment. You won’t have to leave the email to select the date, time, your nearest location, or to complete the booking itself.
This is just one example of how you can leverage AMP components in email. See more examples here. The next GIF shows another example, where the user can switch between different images in a carousel — right from within their email.
Let’s take a look at what it takes to build such a carousel experience.
Implementing interactive email frontends
As AMP components are web components, they are used like standard HTML markup. The following two code snippets show the markup to provide such a carousel experience as shown previously.
When you look at the head markup in the first code block, you’ll see that:
- The first action is to load the core framework.
- Then you load the AMP component(s) asynchronously. In our case, it’s one component,
amp-carousel.
- Within the
style tag you can then define any custom styling for the used AMP components.
");else if(O._boomrl=function(){t()},O.addEventListener)O.addEventListener("load",O._boomrl,!1);else if(O.attachEvent)O.attachEvent("onload",O._boomrl);d.close()}function a(e){window.BOOMR_onload=e&&e.timeStamp||(new Date).getTime()}if(!window.BOOMR||!window.BOOMR.version&&!window.BOOMR.snippetExecuted){window.BOOMR=window.BOOMR||{},window.BOOMR.snippetStart=(new Date).getTime(),window.BOOMR.snippetExecuted=!0,window.BOOMR.snippetVersion=12,window.BOOMR.url=n+"96ZND-LJLSH-JXHC9-F8GQP-6WCGS";var o=document.currentScript||document.getElementsByTagName("script")[0],i=!1,r=document.createElement("link");if(r.relList&&"function"==typeof r.relList.supports&&r.relList.supports("preload")&&"as"in r)window.BOOMR.snippetMethod="p",r.href=window.BOOMR.url,r.rel="preload",r.as="script",r.addEventListener("load",e),r.addEventListener("error",function(){t(!0)}),setTimeout(function(){if(!i)t(!0)},3e3),BOOMR_lstart=(new Date).getTime(),o.parentNode.appendChild(r);else t(!1);if(window.addEventListener)window.addEventListener("load",a,!1);else if(window.attachEvent)window.attachEvent("onload",a)}}(),"".length>0)if(e&&"performance"in e&&e.performance&&"function"==typeof e.performance.setResourceTimingBufferSize)e.performance.setResourceTimingBufferSize();!function(){if(BOOMR=e.BOOMR||{},BOOMR.plugins=BOOMR.plugins||{},!BOOMR.plugins.AK){var n=""=="true"?1:0,t="",a="eyab6kadmwalajqacqefiaaabvvf24vd-f-77f3c38d0-clienttons-s.akamaihd.net",o="false"=="true"?2:1,i={"ak.v":"41","ak.cp":"1836958","ak.ai":parseInt("1224868",10),"ak.ol":"0","ak.cr":2,"ak.ipv":6,"ak.proto":"h2","ak.rid":"2f1ec18f","ak.r":40758,"ak.a2":n,"ak.m":"dsca","ak.n":"essl","ak.cport":59814,"ak.gh":"104.78.78.22","ak.quicv":"","ak.tlsv":"tls1.3","ak.0rtt":"","ak.0rtt.ed":"","ak.csrc":"-","ak.acc":"","ak.t":"1784509091","ak.ak":"hOBiQwZUYzCg5VSAfCLimQ==chOnnmRh1XTMd8WwxBqVDGFjp0UnTa7+6MIbiAn+jK/xoCBVIQRyKF8o+HKqCHent3IEPHMMQakBql/iaVL4fZ+f6F8VAnMbBR07jXcoAkwryDVVFTkYZzgAy7rHgEnWxDvP7nJb46TaH4rKWday/wWe4nISryVAAnm1yOhxfie3tYmgNFXerht8jvJXh6w9LW4nLCWTw0B56wBw1iSWqB9LGuWUEx7B0iBhsSen0Y2gBCIB0Qpq80MmTmxifKvBjDha/PHF90fb4ELgZo8lU1RhVJs5ACEOAgHRRlQrVyw0jFcWSqYdl+cayltPvnKuOlYlOeCAF67uE0hQRazXWn/W0DqqvqHEAVyyw5krT7lb/1SmKOiOE3oz5htRu6XmxZkBbj5uWJKhGzXZ/M4tqIfMQH4yGpHV+Xp7T42iqr0=","ak.pv":"99","ak.dpoabenc":"","ak.tf":o};if(""!==t)i["ak.ruds"]=t;var r={i:!1,av:function(n){var t="http.initiator";if(n&&(!n[t]||"spa_hard"===n[t]))i["ak.feo"]=void 0!==e.aFeoApplied?1:0,BOOMR.addVar(i)},rv:function(){var e=["ak.cport","ak.cr","ak.csrc","ak.gh","ak.ipv","ak.m","ak.n","ak.ol","ak.proto","ak.quicv","ak.tlsv","ak.0rtt","ak.0rtt.ed","ak.r","ak.acc","ak.t","ak.tf"];BOOMR.removeVar(e)}};BOOMR.plugins.AK={akVars:i,akDNSPreFetchDomain:a,init:function(){if(!r.i){var e=BOOMR.subscribe;e("before_beacon",r.av,null,null),e("onbeacon",r.rv,null,null),r.i=!0}return this},is_complete:function(){return!0}}}}()}(window);
...
">
In the second code block, we’ll take a look at the markup to integrate an AMP component into the HTML body. And no worries, it’s markup only.
- The
amp-carousel gets integrated like every other HTML tag. The tag attributes are specific to the carousel and will vary for other AMP components.
- Within the
amp-carousel tag you can use any HTML, like we used to implement the links and the images. Note, the images are also AMP components, as you can identify them via the amp-img tag. You don’t have to load these separately in the HTML header though, as they ship as part of the base AMP framework.
");else if(O._boomrl=function(){t()},O.addEventListener)O.addEventListener("load",O._boomrl,!1);else if(O.attachEvent)O.attachEvent("onload",O._boomrl);d.close()}function a(e){window.BOOMR_onload=e&&e.timeStamp||(new Date).getTime()}if(!window.BOOMR||!window.BOOMR.version&&!window.BOOMR.snippetExecuted){window.BOOMR=window.BOOMR||{},window.BOOMR.snippetStart=(new Date).getTime(),window.BOOMR.snippetExecuted=!0,window.BOOMR.snippetVersion=12,window.BOOMR.url=n+"96ZND-LJLSH-JXHC9-F8GQP-6WCGS";var o=document.currentScript||document.getElementsByTagName("script")[0],i=!1,r=document.createElement("link");if(r.relList&&"function"==typeof r.relList.supports&&r.relList.supports("preload")&&"as"in r)window.BOOMR.snippetMethod="p",r.href=window.BOOMR.url,r.rel="preload",r.as="script",r.addEventListener("load",e),r.addEventListener("error",function(){t(!0)}),setTimeout(function(){if(!i)t(!0)},3e3),BOOMR_lstart=(new Date).getTime(),o.parentNode.appendChild(r);else t(!1);if(window.addEventListener)window.addEventListener("load",a,!1);else if(window.attachEvent)window.attachEvent("onload",a)}}(),"".length>0)if(e&&"performance"in e&&e.performance&&"function"==typeof e.performance.setResourceTimingBufferSize)e.performance.setResourceTimingBufferSize();!function(){if(BOOMR=e.BOOMR||{},BOOMR.plugins=BOOMR.plugins||{},!BOOMR.plugins.AK){var n=""=="true"?1:0,t="",a="eyab6kadmwalajqacqefiaaabvvf24vd-f-77f3c38d0-clienttons-s.akamaihd.net",o="false"=="true"?2:1,i={"ak.v":"41","ak.cp":"1836958","ak.ai":parseInt("1224868",10),"ak.ol":"0","ak.cr":2,"ak.ipv":6,"ak.proto":"h2","ak.rid":"2f1ec18f","ak.r":40758,"ak.a2":n,"ak.m":"dsca","ak.n":"essl","ak.cport":59814,"ak.gh":"104.78.78.22","ak.quicv":"","ak.tlsv":"tls1.3","ak.0rtt":"","ak.0rtt.ed":"","ak.csrc":"-","ak.acc":"","ak.t":"1784509091","ak.ak":"hOBiQwZUYzCg5VSAfCLimQ==chOnnmRh1XTMd8WwxBqVDGFjp0UnTa7+6MIbiAn+jK/xoCBVIQRyKF8o+HKqCHent3IEPHMMQakBql/iaVL4fZ+f6F8VAnMbBR07jXcoAkwryDVVFTkYZzgAy7rHgEnWxDvP7nJb46TaH4rKWday/wWe4nISryVAAnm1yOhxfie3tYmgNFXerht8jvJXh6w9LW4nLCWTw0B56wBw1iSWqB9LGuWUEx7B0iBhsSen0Y2gBCIB0Qpq80MmTmxifKvBjDha/PHF90fb4ELgZo8lU1RhVJs5ACEOAgHRRlQrVyw0jFcWSqYdl+cayltPvnKuOlYlOeCAF67uE0hQRazXWn/W0DqqvqHEAVyyw5krT7lb/1SmKOiOE3oz5htRu6XmxZkBbj5uWJKhGzXZ/M4tqIfMQH4yGpHV+Xp7T42iqr0=","ak.pv":"99","ak.dpoabenc":"","ak.tf":o};if(""!==t)i["ak.ruds"]=t;var r={i:!1,av:function(n){var t="http.initiator";if(n&&(!n[t]||"spa_hard"===n[t]))i["ak.feo"]=void 0!==e.aFeoApplied?1:0,BOOMR.addVar(i)},rv:function(){var e=["ak.cport","ak.cr","ak.csrc","ak.gh","ak.ipv","ak.m","ak.n","ak.ol","ak.proto","ak.quicv","ak.tlsv","ak.0rtt","ak.0rtt.ed","ak.r","ak.acc","ak.t","ak.tf"];BOOMR.removeVar(e)}};BOOMR.plugins.AK={akVars:i,akDNSPreFetchDomain:a,init:function(){if(!r.i){var e=BOOMR.subscribe;e("before_beacon",r.av,null,null),e("onbeacon",r.rv,null,null),r.i=!0}return this},is_complete:function(){return!0}}}}()}(window);
...
...