AMP
  • websites

amp-script

An amp-script hello world example.

Setup

First, you need to import the amp-script extension.

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

For inline scripts you need to generate a CSP header. Read more about this in the component documentation.

<meta name="amp-script-src" content="sha384-X8xW7VFd-a-kgeKjsR4wgFSUlffP7x8zpVmqC6lm2DPadWUnwfdCBJ2KbwQn6ADE sha384-nNFaDRiLzgQEgiC5kP28pgiJVfNLVuw-nP3VBV-e2s3fOh0grENnhllLfygAuU_M sha384-u7NPnrcs7p4vsbGLhlYHsId_iDJbcOWxmBd9bhVuPoA_gM_he4vyK6GsuvFvr2ym">

Basic usage

An amp-script element can load a JavaScript file from a URL. This is usually the best way to integrate a script as the browser needs to download the script only once.

<amp-script layout="container"
  src="https://amp.dev/documentation/examples/components/amp-script/hello-world.js"
  class="amp-script-sample">
  <button id="hello">Click!</button>
</amp-script>

This is the script in hello-world.js:

const button = document.querySelector('#hello');
button.addEventListener('click', () => {
  const h1 = document.createElement('h1');
  h1.textContent = 'Hello World!';
  document.body.appendChild(h1);
});

Inline Scripts

You can also declare scripts inline and reference them by id.

<amp-script layout="container"
  script="hello-world"
  class="amp-script-sample">
  <button id="hello2">Click!</button>
</amp-script>

This is the inlined script. Note that the type needs to be type=text/plain and the target=amp-script.

<script id="hello-world"
  type="text/plain"
  target="amp-script">
  const button = document.querySelector('#hello2');
  button.addEventListener('click', () => {
    const h1 = document.createElement('h1');
    h1.textContent = 'Hello World 2!';
    document.body.appendChild(h1);
  });
</script>

document.body refers to the amp-script tag and not the actual body tag. document.body.appendChild(...) actually adds an element inside the amp-script element.

Using the fetch API

amp-script supports using the fetch API. To be able to update the page on load, we need to use the fixed-height layout instead of the container layout (and the height needs to be less than 300px).

The time is:
<amp-script layout="fixed-height"
  height="32"
  script="time-script"
  class="amp-script-sample">
  <div>The time is: <span id="time"></span></div>
</amp-script>

As amp-script code is executed inside a web worker, fetch only works with absolute URLs.

<script id="time-script"
  type="text/plain"
  target="amp-script">
  const fetchCurrentTime = async () => {
    const response = await fetch('https://amp.dev/documentation/examples/api/time');
    const data = await response.json();
    const div = document.querySelector('#time');
    div.textContent = data.time;
  }
  fetchCurrentTime();
</script>

Detecting Android vs iOS in AMP

amp-script is great to implement functionality not offered by AMP out-of-the-box. Here is a sample that checks if the current device is using Android or iOS.

Your user-agent is: other
<amp-script layout="container"
  script="user-agent-script"
  class="amp-script-sample">
  <div>Your user-agent is: <span id="user-agent">other</span></div>
</amp-script>

The script implementation retrieves the mobile operating system from the user agent string.

<script id="user-agent-script"
  type="text/plain"
  target="amp-script">
  function getMobileOperatingSystem() {
      const userAgent = navigator.userAgent;
      if (/android/i.test(userAgent)) {
        return "Android";
      }
      // iOS detection from: http://stackoverflow.com/a/9039885/177710
      if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
        return "iOS";
      }

      return "other";
    }

    const span = document.querySelector('#user-agent');
    span.textContent = getMobileOperatingSystem();

    const pre = document.createElement('pre');
    pre.textContent = navigator.userAgent;
    span.appendChild(pre);

</script>
Need further explanation?

If the explanations on this page don't cover all of your questions feel free to reach out to other AMP users to discuss your exact use case.

Go to Stack Overflow
An unexplained feature?

The AMP project strongly encourages your participation and contributions! We hope you'll become an ongoing participant in our open source community but we also welcome one-off contributions for the issues you're particularly passionate about.

Edit sample on GitHub