amp-bind

Edit on Github
Open in Playground View Demo

Introduction

amp-bind allows you to add custom interactivity to your pages beyond using AMP's pre-built components.

It works by mutating elements in response to user actions via data binding and JS-like expressions.

For example, amp-bind can be used to:

  • Link two amp-carousel components into an image gallery with a scrolling thumbnail list.
  • Create an e-commerce product page where the UI changes if the user's currently selected item is not available.

Setup

Import the amp-bind component in the header.

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

Configuring initial state

amp-bind works by binding elements to an implicit JSON "state". This state can be initialized with one or more <amp-state> components.

Example

<amp-state id="allAnimals">
  <script type="application/json">
    {
      "dog": {
        "imageUrl": "/img/Border_Collie.jpg",
        "videoUrl": "/video/dog-video.mp4",
        "style": "greenBackground",
        "iframeUrl": "https://player.vimeo.com/video/183849543"
      },
      "cat": {
        "imageUrl": "/img/cat-looking-up-300x200.jpg",
        "videoUrl": "/video/cat-video.mp4",
        "style": "redBackground",
        "iframeUrl": "https://player.vimeo.com/video/185199565"
      }
    }
  </script>
</amp-state>

Referencing implicit state in binding expressions is done using dot or bracket syntax, starting with the <amp-state> element's id, e.g. allAnimals.dog.imageUrl or allAnimals['cat']['imageUrl'].

  • The contents of <amp-state> must be a single JSON script.
  • Similar to the <amp-analytics> config, placing metadata at the end of the document helps the page display more quickly.

Creating data bindings

A data binding is a link between an HTML element and an expression. When the expression's value changes, the element is updated with that value.

Three types of element state can be bound:

  1. text for textContent
  2. class for CSS classes
  3. Element-specific attributes, for example, the src attribute for amp-img or amp-video.

    To create a binding, create a new attribute on an element with the syntax:

    [attribute]="expression"

Binding Text

The text of this <p> will change when the currentAnimal variable changes. currentAnimal is an uninitialized implicit state variable, which will be set when a state change is triggered (see below).

Example

This is a dog.

<p [text]="'This is a ' + currentAnimal + '.'">This is a dog.</p>

Binding Styles

Styling can be changed by applying CSS classes, which will override all the element's style classes. In the next example, allAnimals is the id of the amp-state component above and we use bracket notation because currentAnimal is a variable.

Example

Each animal has a different background color.

<p [class]="allAnimals[currentAnimal].style"
  class="greenBackground">Each animal has a different background color.</p>

Binding Attribute Values

Various AMP components support binding attribute values with amp-bind:

amp-img URLs can be changed.

Example

<amp-img id="amp-img"
  src="/img/Border_Collie.jpg"
  layout="responsive"
  width="300"
  height="200"
  [src]="allAnimals[currentAnimal].imageUrl">
</amp-img>

The src URL for videos embedded with amp-video can be changed. At the moment, among all the AMP video components, amp-video and amp-youtube support amp-bind.

Example

<amp-video id="amp-video"
  src="/video/dog-video.mp4"
  layout="responsive"
  [src]="allAnimals[currentAnimal].videoUrl"
  width="300"
  height="170"
  autoplay
  controls></amp-video>

The src for iframes embedded with amp-iframe can be changed.

Example

<amp-iframe id="amp-iframe"
  width="500"
  height="281"
  layout="responsive"
  sandbox="allow-scripts allow-same-origin allow-popups"
  allowfullscreen
  frameborder="0"
  src="https://player.vimeo.com/video/183849543"
  [src]="allAnimals[currentAnimal].iframeUrl">
</amp-iframe>

Triggering updates

Data bindings are re-evaluated when implicit state changes. Implicit state can be updated via the AMP.setState action.

  • AMP.setState merges new state into existing implicit state
  • Existing state can be overwritten, including state initialized by amp-state components

Example

<button class="ampstart-btn caps m1"
  on="tap:AMP.setState({currentAnimal: 'cat'})">Set to Cat</button>