Edit on Github
Open in Playground View Demo

Experimental Mode

This example uses the following experimental feature: [amp-bind]. Enable the experiment via the button below. Some components require the AMP Dev Channel to be enabled as well. Learn more here.

Enable Dev Channel


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.


Import the amp-bind component in the header.

<script async custom-element="amp-bind" src=""></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.


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

Referencing implicit state in binding expressions is done using dot or bracket syntax, starting with the <amp-state> element's id, e.g. 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:


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).


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.


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. For example, amp-img URLs can be changed.


<amp-img src="/img/Border_Collie.jpg"

The src URL for videos embedded with amp-video can also be changed. At the moment, among all the AMP video components, only amp-video supports amp-bind.


<amp-video src="/video/dog-video.mp4"

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


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