Products by Example

Fruit

Vegetable

More

View Demo

Product

Edit on Github

Experimental Mode

This example uses the following experimental features: [amp-form-var-subamp-bind]
Enable them below and learn more here.

Enable Dev Channel

Introduction

This sample showcases how to build a product page in AMP HTML.

Show Hidden Code Hide Code
<!doctype html>
<html ⚡>
<head>
    <meta charset="utf-8">
    <script async src="https://cdn.ampproject.org/v0.js"></script>

    <script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
    <script async custom-element="amp-accordion" src="https://cdn.ampproject.org/v0/amp-accordion-0.1.js"></script>
    <script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
    <script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
    <script async custom-element="amp-social-share" src="https://cdn.ampproject.org/v0/amp-social-share-0.1.js"></script>
    <script async custom-element="amp-lightbox" src="https://cdn.ampproject.org/v0/amp-lightbox-0.1.js"></script>
    <script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script>
    <script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
    <script async custom-element="amp-sidebar" src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"></script>
    <script async custom-element="amp-selector" src="https://cdn.ampproject.org/v0/amp-selector-0.1.js"></script>
    <script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
    <script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>

    <link rel="canonical" href="https://ampbyexample.com/samples_templates/product/">
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <style amp-custom>
    /* general styling */
    article#preview {
      background-color: #f5f5f5;
    }
    amp-carousel {
      margin: 0;
    }
    /* header with logo and carousel */
    .header {
      position: relative;
      box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
      padding-top: 52px;
    }
    .header {
      background-color: #607D8B;
    }
    .header #sample-menu {
      position:absolute;
      top:0;
      left: 0;
      font-size: 18px;
      font-weight: 500;
      color: white;
      text-transform: uppercase;
      padding: 13px;
    }
    .header #sample-logo {
      position:absolute;
      top:0;
      left:36px;
      font-size: 18px;
      font-weight: 400;
      color: white;
      text-transform: uppercase;
      margin: 16px;
      height: 32px;
    }
    /* search form */
    .header form {
      padding: 0;
    }
    .header input::-webkit-search-decoration,
    .header input::-webkit-search-cancel-button {
      display: none;
    }
    .header input[type=submit] {
      position:absolute;
      top:10px; right:8px;
      background-color: #eb407a;
      background-position: center;
      background-repeat: no-repeat;
      background-image: -webkit-image-set(
        url('/img/ic_search_white_1x_web_24dp.png') 1x,
        url('/img/ic_search_white_2x_web_24dp.png') 2x
      );
      border: 0 none;
      height: 32px;
      width: 36px;
      -webkit-appearance: none;
      border-radius: 0;
      -moz-border-top-right-radius: 4px;
      -moz-border-bottom-right-radius: 4px;
      -webkit-border-top-right-radius: 4px;
      -webkit-border-bottom-right-radius: 4px;
      border-top-right-radius: 4px;
      border-bottom-right-radius: 4px;
    }
    .header input[type=search] {
      position: absolute;
      top: 10px; 
      right: 24px;
      background: #ededed ;
      padding: 0 8px;
      width: 20vw;
      height: 32px;
      font-family: inherit;
      font-size: 100%;
      -moz-box-sizing: border-box;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      -webkit-appearance: none;
      border: solid 0px #ccc;
      border-radius: 0;
      -moz-border-top-left-radius: 4px;
      -moz-border-bottom-left-radius: 4px;
      -webkit-border-top-left-radius: 4px;
      -webkit-border-bottom-left-radius: 4px;
      border-top-left-radius: 4px;
      border-bottom-left-radius: 4px;
      -webkit-transition: all .9s;
      -moz-transition: all .9s;
      transition: all .9s ease;
    }
    .header input[type=search]:focus {
      box-sizing: border-box;
      width: 80vw;
      max-width: 700px;
      height: 32px;
      background-color: #fff;
      border-color: #eb407a;
      -webkit-box-shadow: 0 0 5px rgba(109,207,246,.5);
      -moz-box-shadow: 0 0 5px rgba(109,207,246,.5);
      box-shadow: 0 0 5px rgba(109,207,246,.5);
      outline:none;
    }
    .header input:-moz-placeholder,
    .header input::-webkit-input-placeholder {
      color: #999;
    }
    .header input:focus + #sample-logo {
      visibility: hidden;
      opacity: 0;
      transition: visibility 0s 0.7s, opacity 0.7s ease;
    }
    .header input + #sample-logo {
      visibility: visible;
      opacity: 1;
      transition: opacity 1.5s ease;
    }
    @media (min-width: 600px) {
      .header input[type=search] {
        width: 100px;
      }
      .header input[type=search]:focus {
        width: 600px;
      }
    }
    /* items */
    .items,
    amp-list.items > div {
      display: flex;
      justify-content:space-around;
      flex-wrap: wrap;
    }
    .item {
      flex-grow: 1;
      flex-shrink: 1;
    }
    /* tiles */
    .tile {
      background-color: white;
      width: 120px;
      height: 200px;
      display: block;
      margin: 8px;
      -webkit-tap-highlight-color: #eee;
      max-width: 200px;
    }
    @media (max-width: 500px) {
      .items .tile {
        width: 150px;
        height: 200px;
      }
    }
    .tile:active {
      background-color: #eee;
    }
    .tile p {
      margin: 0;
      padding: 0 8px;
      font-size: 14px;
      line-height:20px;
    }
    .tile .name {
      margin-top: 8px;
    }
    .tile .price {
      margin-bottom: 8px;
    }
    .tile .price,
    .tile .star {
      color: black;
    }
    #product-description {
      clear: both;
    }
    amp-lightbox {
      background: rgba(0,0,0,0.8);
      width: 100%;
      height: 100%;
      position: absolute;
    }
    amp-accordion p, amp-accordion h4 {
      padding: 16px;
    }
    amp-accordion h4 {
      font-size: 18px;
    }
    amp-carousel .selected {
      border: solid 2px red;
    }
    .play {
      padding-left: 28px;
      background-position: left center;
      background-repeat: no-repeat;
      background-image: -webkit-image-set(url(/img/ic_play_circle_filled_black_1x_web_24dp.png) 1x,url(/img/ic_play_circle_filled_black_2x_web_24dp.png) 2x);
    }
    .amp-youtube-container {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
    }
    #video-container, #social, form .button {
      margin: 16px;
    }
    .video {
      flex: 1;
    }
    .price-description {
      color: grey;
      font-weight: 400;
      margin-top: 24px;
      margin-bottom: 16px;
      padding: 0 16px;
    }
    .quantity {
      margin: 16px 0;
    }
    .product-gallery > ul {
      margin: 0;
      padding: 0;
      float: left;
      list-style: none;
      line-height: 0;
    }
    .product-gallery > ul > li {
      cursor: pointer;
      margin: 0 8px 8px 8px;
      opacity: 1;
      will-change: opacity;
      transition: all 0.3s cubic-bezier(.25,.8,.25,1);
    }
    .product-gallery > ul > li:active {
      opacity: 0.5;
    }
    .product-gallery > ul > li:focus {
      outline: none;
    }
    form#order {
      display: flex;
    }
    form#order label {
      display: inline;
      font-weight: 500;
      font-size: 16px;
      margin: 0;
    }
    form#order div {
      display: flex;
      align-items: center;
    }
    form#order .button {
      width: 100%;
      max-width: 400px;
      align-self: center;
      margin: 16px 20%;
      box-sizing: border-box;
    }
    form#order.amp-form-submitting [name=add-to-cart] {
      color: #666;
      background-color: #aaa;
      cursor: default;
    }
    form#order amp-selector > ul {
      list-style: none;
      display: flex;
      align-items: flex-end;
      justify-content: end;
    }
    form#order amp-selector > ul li {
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 8px;
      background: white;
      height: 40px;
      min-width: 40px;
      width: auto;
    }
    form#order amp-selector [option] {
      outline: none;
    }
    form#order amp-selector amp-img[option][selected] {
      outline-width: 1px;
      outline-style: solid;
      outline-color: #eb407a;
      background: none;
    }
    form#order amp-selector:not([disabled]) [option][selected]:not([disabled]), amp-img.selected {
      will-change: box-shadow;
      box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
      transition: box-shadow 0.3s cubic-bezier(.25,.8,.25,1);
      color: #fff;
    }

    form#order amp-selector:not([disabled]) [option][selected]:not([disabled]):not(.unavailable):not(.square) {
      background-color: #eb407a;
    }

    form#order amp-selector:not([disabled]) [option][selected]:not([disabled]):not(.unavailable).square {
      outline: 1px solid #eb407a;
    }

    form#order amp-selector:not([disabled]) [option]:not([selected]):not([disabled]), amp-img:not([.selected]) {
      will-change: box-shadow;
      box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
      transition: box-shadow 0.3s cubic-bezier(.25,.8,.25,1);
    }

    form#order amp-selector[name=color] div:not([selected]):not([disabled]) {
      opacity: 0.6;
    }
    .hide {
      display: none;
    }
    .show {
      display: block;
    }
    .unavailable {
      position: relative;
      background: gray;
      overflow: hidden;
      opacity: 0.6;
      pointer-events: none;
      user-select: none;
    }

.unavailable:before, .unavailable:after {
    position: absolute;
    content: '';
    background: grey;
    display: block;
    width: auto;
    height: 1px;
    min-width: 56px;
    -webkit-transform: rotate(-45deg);
    transform: rotate(-45deg);
    left: -8px;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}

.unavailable:after {
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}

div.square {
  width: 40px;
  height: 40px;
}

.green {
    background-color: #008000;
}

.red {
    background-color: #FF0000;
}

.golden{
    background-color: #DAA520;
}

@media (max-width: 1024px) {
  .product-gallery > ul {
    display: none;
  }
}

    </style>

Metadata

The page indexing requires schema.org markup for one of the following types: Type, AggregateRating, Offers. Learn more.

    <script type="application/ld+json">
    {
        "@context": "http://schema.org/",
        "@type": "Product",
        "name": "Apple",
        "image": "http://www.ampbyexample.com/img/golden_apple1_1024x682.jpg",
        "description": "Lorem ipsum",
        "mpn": "925872",
        "brand": {
            "@type": "Fruit",
            "name": "Apple"
        },
        "aggregateRating": {
            "@type": "AggregateRating",
            "ratingValue": "4.4",
            "reviewCount": "88"
        },
        "offers": {
            "@type": "Offer",
            "priceCurrency": "USD",
            "price": "1.99",
            "priceValidUntil": "2020-11-05",
            "itemCondition": "http://schema.org/UsedCondition",
            "availability": "http://schema.org/InStock",
            "seller": {
                "@type": "Retail",
                "name": "AMP by Example"
            }
        }
    }
    </script>
Show Hidden Code Hide Code

    <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
    </head>
<body>

Use the amp-sidebar component to give customers the chance to quickly jump to any of your product categories.

  <amp-sidebar id="drawermenu" layout="nodisplay">
    <div class="topheader">
      <a href="/" class="home">Products by Example</a>
    </div>
    <hr/>
    <h4 class="category expanded">
      <a href="/samples_templates/product_listing/preview/">Fruit</a>
    </h4>
    <h4 class="category">
      <a href="/samples_templates/product_listing/preview/">Vegetable</a>
    </h4>
    <h4 class="category">
      <a href="/samples_templates/product_listing/preview/">More</a>
    </h4>
  </amp-sidebar>

AMP supports forms, which means you can directly integrate a product search into your AMPs. Try searching for "Apple".

AMP doesn't support custom Javascript, but you can use CSS3 animations to enrich your page. The expanding text field when the search box is focused is implemented with CSS only.

  <div class="header">
    <a id="sample-menu" on="tap:drawermenu.toggle">
      <amp-img srcset="/img/ic_menu_white_1x_web_24dp.png 1x, /img/ic_menu_white_2x_web_24dp.png 2x" width="24" height="24" alt="navigation"></amp-img>
    </a>
    <form method="GET" action="/samples_templates/product_listing/search" target="_top">
      <input name="search" type="search" placeholder="Search">
      <a id="sample-logo" href="/">Products by Example</a>
      <input type="submit" value="">
    </form>
  </div>

  <h2>Apple</h2>

Apple

Social Sharing

The Social Share extension provides a common interface for share buttons. Learn more about amp-social-share here.

  <div id="social">
    <amp-social-share type="twitter" width="30" height="22"></amp-social-share>
    <amp-social-share type="facebook" width="30" height="22" data-attribution="254325784911610"></amp-social-share>
    <amp-social-share type="gplus" width="30" height="22"></amp-social-share>
    <amp-social-share type="email" width="30" height="22"></amp-social-share>
    <amp-social-share type="pinterest" width="33" height="22"></amp-social-share>
  </div>

  <p id="product-description">Lorem ipsum dolor sit amet, ut sed non vel mattis. Et nulla suscipit ante ligula nisl in. Ut venenatis et mauris, mauris porta vulputate tellus mauris integer facilisis.</p>

Lorem ipsum dolor sit amet, ut sed non vel mattis. Et nulla suscipit ante ligula nisl in. Ut venenatis et mauris, mauris porta vulputate tellus mauris integer facilisis.

Video

AMP supports a wide range of video platforms. Here we are using amp-youtube to show a product video. You can find an overview of all supported video platforms here.

In this sample we don't embed the video directly into the page, but instead show it in a lightbox using the amp-lightbox component. Learn more about amp-lightbox here.


  <div id="video-container">
    <a on="tap:watch-video-lightbox" role="button" class="button button-secondary play" tabindex="0">
      Show Video
    </a>

    <amp-lightbox id="watch-video-lightbox" layout="nodisplay">
      <div class="amp-youtube-container">
        <div class="video">
          <a on="tap:watch-video-lightbox.close" role="button" tabindex="0">
            Close
          </a>
          <amp-youtube width="480" height="270" layout="responsive" data-videoid="lBTCB7yLs8Y">
          </amp-youtube>
        </div>
      </div>
    </amp-lightbox>
  </div>

On desktop we've added a film strip like slide preview. Each product colour has its own image gallery and slide preview. We use amp-bind to update the page selecting the gallery and image preview corresponding to the selected colour. We realized the color selection by using amp-selector. Find more the doc and info in The Product Page section below.

The green colour is the default color for the gallery when the page loads. Clicking on a preview image will reveal the image in the gallery via the tap action on="tap:product-carousel-preview.goToSlide(index=0)".

See below for more informations on how we useamp-bind.

  <div class="product-gallery">
    <ul class="show" [class]="selectedColor == 'green' ? 'show' : 'hide'">
      <li tabindex="0" role="button">
        <amp-img on="tap:AMP.setState(selectedSlide=0)" src="/img/green_apple_1_60x40.jpg" width="60" height="40" class="selected" [class]="selectedSlide == 0 ? 'selected' : '' ">
        </amp-img>
      </li>
      <li tabindex="1" role="button">
        <amp-img on="tap:AMP.setState(selectedSlide=1, selectedColor=green)" src="/img/green_apple_2_60x40.jpg" width="60" height="40" [class]="selectedSlide == 1 ? 'selected' : '' ">
        </amp-img>
      </li>
    </ul>

    <ul class="hide" [class]="selectedColor == 'golden' ? 'show' : 'hide'">
      <li tabindex="0" role="button">
        <amp-img on="tap:AMP.setState(selectedSlide=0)" src="/img/product1_alt1_60x40.jpg" width="60" height="40" [class]="selectedSlide == 0 ? 'selected' : '' ">
        </amp-img>
      </li>
    </ul>

    <ul class="hide" [class]="selectedColor == 'red' ? 'show' : 'hide'">
      <li tabindex="0" role="button">
        <amp-img on="tap:AMP.setState(selectedSlide=0)" src="/img/red_apple_1_60x40.jpg" width="60" height="40" [class]="selectedSlide == 0 ? 'selected' : '' ">
        </amp-img>
      </li>
      <li tabindex="1" role="button">
        <amp-img on="tap:AMP.setState(selectedSlide=1, selectedColor=red)" src="/img/red_apple_2_60x46.jpg" width="60" height="40" [class]="selectedSlide == 1 ? 'selected' : '' ">
        </amp-img>
      </li>
    </ul>
  </div>

The amp-carousel component works very well for product image galleries. Learn how the amp-carousel component works here.

Notice how we are binding to the slide and class by using to the values of the variables selectedSlide and selectedColor.

  <div class="product-gallery">

    <amp-carousel id="green-apple-carousel" width="1024" height="682" layout="responsive" type="slides" [slide]="selectedSlide" on="goToSlide:AMP.setState(selectedSlide=event.index, selectedColor=green)" class="show" [class]="selectedColor == 'green' ? 'show' : 'hide'">
      <amp-img src="/img/green_apple_1_1024x682.jpg" width="1024" height="682" layout="responsive">
      </amp-img>
      <amp-img src="/img/green_apple_2_1024x685.jpg" width="1024" height="682" layout="responsive">
      </amp-img>
    </amp-carousel>

    <amp-carousel id="golden-apple-carousel" width="1024" height="682" layout="responsive" type="slides" [slide]="selectedSlide" on="goToSlide:AMP.setState(selectedSlide=event.index, selectedColor=golden)" class="hide" [class]="selectedColor == 'golden' ? 'show' : 'hide'">
      <amp-img src="/img/golden_apple1_1024x682.jpg" width="1024" height="682" layout="responsive">
      </amp-img>
    </amp-carousel>

    <amp-carousel id="red-apple-carousel" width="1024" height="682" layout="responsive" type="slides" [slide]="selectedSlide" on="goToSlide:AMP.setState(selectedSlide=event.index, selectedColor=red)" class="hide" [class]="selectedColor == 'red' ? 'show' : 'hide'">
      <amp-img src="/img/red_apple_1_1024x682.jpg" width="1024" height="682" layout="responsive">
      </amp-img>
      <amp-img src="/img/red_apple_2_1024x793.jpg" width="1024" height="682" layout="responsive">
      </amp-img>
    </amp-carousel>

  </div>

Product Configuration

We use the amp-state component (part of amp-bind) to configure the product price depending on the color and the size. We also configure the defaultSize for each product when you switch between colours

  <amp-state id="product">
    <script type="application/json">
      {
        "green": {
          "sizes": {
            "S": "$5.99",
            "M": "$5.99",
            "L": "unavailable"
          },
          "defaultSize": "S"
        },
        "golden": {
          "sizes": {
            "S": "$9.99",
            "M": "unavailable",
            "L": "$9.99"
          },
          "defaultSize": "S"
        },
        "red": {
          "sizes": {
            "S": "$7.99",
            "M": "$7.99",
            "L": "$7.99"
          },
          "defaultSize": "S"
        }
      }
    </script>
  </amp-state>

Product price

We use amp-bind to update the price of the product depending on the selected colour.

We bind the text attribute to the value of expression product[selectedColor].price. product is the id amp-state json described in the Product Configuration section.

Notice how we set a default value for the price: values defined inside amp-state will not be accessed at the page load. We set green and S as default color and default size as the correspondent variables have null value at default.

We use amp-selector together with amp-bind to update the page for showing the price, the size availability, the gallery and preview of images. Every time you select a color, we set the expression selectedColor=event.targetOption. This is triggering all the attributes and elements binded to selectedColor to update: the price (binded with the attribute [text]), the gallery, the image preview and the size selector (all binded with [class]).

  <p class="price-description">Price:
    <span [text]="product[selectedColor || 'green'].sizes[selectedSize || 'S']">$1.99</span>
  </p>

Price: $1.99

Product page

The add-to-cart action action is implemented using amp-form. In our sample we use the amp-selector for selecting different product properties. Pressing the ADD TO CART button adds the product to a shopping cart page using the properties you have selected. Notice that the button URL contains the query clientId={{ClientId}}. If an item is successfully added to the shopping cart, we redirect the user to the shopping cart page. The redirect target is configured via a header in the server's form response (redirecting after submission):

access-control-expose-headers:AMP-Access-Control-Allow-Source-Origin,AMP-Redirect-To
amp-redirect-to:http://ampbyexample.com/shopping_cart/?clientid=amp-123456789 

We use the CLIENT_ID variable to identify the user, this enables storing a shopping cart between repeated visits of an AMP page (either via the AMP Cache or the original host). This variable can be used inside an amp-form by declaring an hidden input value with default-value="CLIENT_ID(cart). Read more about variable substitution here.


  <form id="order" method="POST" action-xhr="/samples_templates/product/add_to_cart" target="_top">
    <div>
      <label for="color">Color:</label>
      <amp-selector name="color" layout="container" [selected]="selectedColor" on="select:AMP.setState(selectedColor=event.targetOption, selectedSlide=0, selectedSize='S')">
        <ul>
          <li>
            <div option="green" selected class="square green" width="40" height="40"></div>
          </li>
          <li>
            <div option="golden" class="square golden" width="40" height="40"></div>
          </li>
          <li>
            <div option="red" class="square red" width="40" height="40"></div>
          </li>
        </ul>
      </amp-selector>
    </div>
    <div>
      <label for="quantity">Quantity:</label>
      <amp-selector name="quantity" layout="container">
        <ul>
          <li option="1" selected>1</li>
          <li option="2">2</li>
          <li option="3">3</li>
        </ul>
      </amp-selector>
    </div>
    <div>
      <label for="size">Size:</label>
      <amp-selector name="size" layout="container" on="select:AMP.setState(selectedSize=event.targetOption)" [selected]="product[selectedColor || 'green'].sizes[selectedSize || 'S'] != 'unavailable' ? selectedSize : product[selectedColor || 'green'].defaultSize">
        <ul>
          <li option="S" class="" [class]="product[selectedColor || 'green'].sizes['S'] != 'unavailable' ? '' : 'unavailable'">S</li>
          <li option="M" class="" selected [class]="product[selectedColor || 'green'].sizes['M'] != 'unavailable' ? '' : 'unavailable'">M</li>
          <li option="L" class="unavailable" [class]="product[selectedColor || 'green'].sizes['L'] != 'unavailable' ? '' : 'unavailable'">L</li>
        </ul>
      </amp-selector>
    </div>
    <input type="submit" class="button button-primary" name="add-to-cart" value="add to cart">
    <input type="hidden" name="name" value="Apple">
    <input type="hidden" name="price" value="$1.99">
    <input name="clientId" type="hidden" value="CLIENT_ID(cart)" data-amp-replace="CLIENT_ID">
    <div submit-error>
      <template type="amp-mustache">
        Error! Looks like something went wrong with your shopping cart, please try to add an item again. {{error}}
      </template>
    </div>
  </form>
  • 1
  • 2
  • 3
  • S
  • M
  • L

Collapsibles/Accordion

Use amp-accordion to hide and show additional data about your product. Learn more about amp-accordion here.

  <div>
    <amp-accordion>
      <section>
        <h4>Description</h4>
        <p>Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut. </p>
      </section>
      <section>
        <h4>Specification</h4>
        <p>Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut. </p>
      </section>
      <section>
        <h4>Measurements</h4>
        <p>Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut. </p>
      </section>
      <section>
        <h4>Other</h4>
        <p>Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut. </p>
      </section>
    </amp-accordion>
  </div>

Description

Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut.

Specification

Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut.

Measurements

Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut.

Other

Lorem ipsum dolor sit amet, mauris id, fermentum natoque ut et ullam dolore egestas. Vitae tortor maecenas nec consequat, nisl vestibulum est est curabitur. Mi eu in pellentesque lectus nostra ut.

  <h5 id="related-products">Related products</h5>

With AMP, you can easily pull in different latest offers or highlights without changing the page. To do so, just use amp-list to fire a CORS request to a JSON endpoint which supplies the list of related products. These are populated into an amp-mustache template on the client. Learn more about amp-list here

  <amp-list class="items" width="200" height="100" layout="responsive" src="/json/related_products.json">
    <template type="amp-mustache">
      <a class="tile item" href="/samples_templates/product/preview/">
        <amp-img width="640" height="426" layout="responsive" alt="{{name}}" src="{{img}}"></amp-img>
        <p class="name">{{name}}</p>
        <p class="star">{{{stars}}}</p>
        <p class="price">${{price}}</p>
      </a>
    </template>
  </amp-list>

User Analytics

Analytics must be configured in the body. Here we use Google Analytics to track pageviews.

  <amp-analytics type="googleanalytics">
    <script type="application/json">
      {
        "vars": {
          "account": "UA-73836974-1"
        },
        "triggers": {
          "default pageview": {
            "on": "visible",
            "request": "pageview",
            "vars": {
              "title": "Product"
            }
          }
        }
      }
    </script>
  </amp-analytics>

Next up:

</body>
</html>