Search code examples
javascriptamp-htmlweb-workernavigator

Which browser APIs does amp-script allow custom JavaScript to access?


Now that we have <amp-script> which allows custom, third-party JavaScript to run on AMP pages, I'm trying to determine whether I still have access to the same info I collect right now on non-AMP pages. E.g. user agent. I have the following example, where I have this code on the page:

<amp-script layout="container" src="/javascripts/alert.js">
  Output message: <span id="outputMsg"></span>
</amp-script>

And I have the this code in the retrieved JS file:

const req = new XMLHttpRequest();
console.log('XHR ctor works');

const collectedData = {
    userAgent: navigator.userAgent,
};
console.log('user agent accessible')

document.cookie = "key=value";
console.log('cookie set works');

document.getElementById('outputMsg').innerHTML = JSON.stringify(collectedData, null, 4);
console.log('DOM mutation works');

The idea is that this would tell me what code is allowed to run under the conditions imposed by <amp-script>. I get the following output in the console:

Powered by AMP ⚡ HTML – Version 1905021827420 http://localhost:3000/search?searchterm=diamond
/javascripts/alert.js:32 XHR ctor works
/javascripts/alert.js:35 Uncaught ReferenceError: navigator is not defined
    at Object.<anonymous> (/javascripts/alert.js:35)
    at /javascripts/alert.js:45

So I can see that some things are allowed and some aren't. I was able to rearrange that code to determine that the only thing in that example that wasn't allowed was accessing the navigator object.

Is there an allowlist of things AMP pages are allowed to do using <amp-script>? I looked in their official docs and was not able to find this information.


Solution

  • Since <amp-script> is powered by WorkerDOM, the best place to look into this is the WorkerDOM documentation.

    Specifically, there is a WorkerDOM compatibility table where you can see which APIs are currently available.

    When it comes to the navigator object, this should be supported via WorkerNavigator. Try using self.navigator.userAgent instead and this should work.