AMP

amp-script

Allows running custom JavaScript to render UI.

Availability Origin Trial
This component is available under Origin Trial. To sign up for an Origin Trial please sign up at bit.ly/amp-script-trial.
Required Script
<script async custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script>
Examples
Tutorials

Overview

The amp-script component allows you run custom JavaScript to render UI elements, such as a React component.

amp-script is in active development and under experimental availability. It's subject to breaking API changes and should not yet be used in production.

A simple example

An amp-script element can load a JavaScript file from a URL:

<!-- Use an remote script via the "src" attribute. -->
<amp-script layout="container" src="https://example.com/hello-world.js">
  <button>Hello amp-script!</button>
</amp-script>

...or reference a local script element by id:

<!-- Reference a local script by id via the "script" attribute. -->
<amp-script layout="container" script="hello-world">
  <button>Hello amp-script!</button>
</amp-script>

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

Enable the experiment via AMP.toggleExperiment('amp-script') in dev console.

How does it work?

amp-script runs your custom JavaScript in a Web Worker that contains a virtual DOM. When your JavaScript code modifies this virtual DOM, amp-script forwards these changes to the main thread and applies them to the amp-script element subtree.

For example, adding an element to document.body:

// my-script.js
const p = document.createElement('p');
p.textContent = 'I am added to the body!';
document.body.appendChild(p);

Will be reflected on the page as a new child of the amp-script element:

<amp-script src="http://example.com/my-script.js" width=300 height=100>
  <p>I am added to the body!</p>
</amp-script>

Under the hood, amp-script uses @ampproject/worker-dom. For design details, see the "Intent to Implement" issue.

Restrictions

Size of JavaScript code

amp-script has the following restrictions on JavaScript file size:

  • Maximum of 10,000 bytes per amp-script element that uses a local script via script[type=text/plain][target=amp-script].
  • Maximum total of 150,000 bytes for all amp-script elements on the page.

User gestures

amp-script generally requires a user gesture to apply changes triggered by your JavaScript code to the page (we call these "mutations"). This requirement helps avoid poor user experience from unexpected content jumping.

The rules for mutations are as follows:

  1. Mutations are always accepted for five seconds after a user gesture.
  2. The five second interval is extended if the author script performs a fetch() as a result of the user gesture.
  3. Mutations are always accepted for amp-script elements with [layout!="container"] and height < 300px.

Attributes

src

The URL of a JS file that will be executed in the context of this <amp-script>.

script

The id of a script[type=text/plain][target=amp-script] element whose text content contains JS that will be executed in the context of this <amp-script>.

sandbox (optional)

Applies extra restrictions to DOM that may be mutated by this <amp-script>. Similar to the iframe[sandbox] attribute, the value of the attribute can either be empty to apply all restrictions, or space-separated tokens to lift particular restrictions:

  • allow-forms: Allows form elements to be created and modified. AMP requires special handling to prevent unauthorized state changing requests from user input. See amp-form's security considerations for more detail.

common attributes

This element includes common attributes extended to AMP components.

Interested in using amp-script?

We recommend developing against a local build of amp-script. This enables dev-only debugging hooks e.g. human-readable postMessage events.

See our Quick Start guide for setting up your local environment.

FAQ

Which JavaScript APIs can I use?

Currently, most DOM elements and their properties are supported. DOM query APIs like querySelector have partial support. Browser APIs like History are not implemented yet.

See the API compatibility table for details.

Can you support ____ API?

Our feature timelines are informed by your real-world use cases! Please file an issue and mention @choumx and @kristoferbaxter.

I'm getting a "size exceeded" error.

See Size of JavaScript code above.

¿Necesitas más ayuda?

You've read this document a dozen times but it doesn't really cover all of your questions? Maybe other people felt the same: reach out to them on Stack Overflow.

Go to Stack Overflow
Found a bug or missing a 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.

Go to GitHub