Find file History
Latest commit 01bb681 Jan 13, 2017 @mmcao mmcao committed with lannka Update csa.md to remove non-required parameters (#6902)
* Update csa.md to remove non-required parameters 

Removed non-required parameters (width, layout) from the amp-ad tag.

* Updated csa.md to combine text in multiple lines
Permalink
..
Failed to load latest commit information.
alp Allow *.cdn.ampproject.org as amp cache origin (#5901) Nov 23, 2016
google Update csa.md to remove non-required parameters (#6902) Jan 14, 2017
inabox Apply rate limit to amp-inabox host event listeners (#6657) Dec 14, 2016
OWNER.yaml add more owners.yaml files (#5781) Nov 4, 2016
README.md Update ads/README.md to inform 3P developer to add fake ad examples. (#… Jan 5, 2017
_a4a-config.js Adding a4a support to TripleLift amp-ads (#6884) Jan 12, 2017
_config.js Ad type adverticumv.2 (#6493) Jan 11, 2017
_integration-guide.md Fix grammar, add link. Obsoletes PR #2994. (#5706) Oct 21, 2016
_ping_.js add integration test to 3p ad (#6789) Jan 6, 2017
a9.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
a9.md Amending indentation or HTML properties Oct 12, 2015
accesstrade.js Add support fro AccessTrade to amp-ad (#4703) Aug 25, 2016
accesstrade.md Add support fro AccessTrade to amp-ad (#4703) Aug 25, 2016
adblade.js fix typos in documentation and call renderStart (#5644) Nov 2, 2016
adblade.md fix typos in documentation and call renderStart (#5644) Nov 2, 2016
adbutler.js AdButler AMP Ad Implementation (#5736) Nov 18, 2016
adbutler.md AdButler AMP Ad Implementation (#5736) Nov 18, 2016
adform.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adform.md Added more valid Adform hosts. Feb 29, 2016
adgeneration.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adgeneration.md Add amp-ad support for Ad Generation (#3572) Jun 17, 2016
adition.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adition.md Integrates adition ad-server (#3010) May 2, 2016
adman.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adman.md request for integrating adman ad-server Apr 7, 2016
adreactor.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adreactor.md Amending indentation or HTML properties Oct 12, 2015
ads.extern.js Integrate Google AdSense for Search and Adsense for Shopping (on the … Dec 22, 2016
adsnative.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adsnative.md adsnative integration (#4373) Aug 11, 2016
adspirit.js Forbid direct style manipulation (#6012) Nov 8, 2016
adspirit.md AdSpirit adapter for AMP (#4007) Jul 25, 2016
adstir.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adstir.md Add support for AdStir ads (#2872) Apr 14, 2016
adtech.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
adtech.md Updates to adtech amp-ad functionality #3462 (#3659) Jun 24, 2016
aduptech.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
aduptech.md Add support for Ad Up Technology ads Apr 8, 2016
adverline.js Adding Adverline to amp-ad (#5829) Oct 28, 2016
adverline.md Adding Adverline to amp-ad (#5829) Oct 28, 2016
adverticum.js Ad type adverticumv.2 (#6493) Jan 11, 2017
adverticum.md Ad type adverticumv.2 (#6493) Jan 11, 2017
advertserve.js Implementation and documentation of AdvertServe <amp-ad> tag (#5366) Oct 12, 2016
advertserve.md Implementation and documentation of AdvertServe <amp-ad> tag (#5366) Oct 12, 2016
affiliateb.js Add Affiliate-B support for amp-ad (#5223) Oct 7, 2016
affiliateb.md Add Affiliate-B support for amp-ad (#5223) Oct 7, 2016
amoad.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
amoad.md addSupportForAMoAdNative (#4268) Aug 17, 2016
appnexus.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
appnexus.md Add AppNexus (#2825) May 3, 2016
atomx.js Add amp-ad support for Atomx (#4566) Aug 29, 2016
atomx.md Add amp-ad support for Atomx (#4566) Aug 29, 2016
caajainfeed.js Support AMP by CA A.J.A. Infeed (#6478) Dec 13, 2016
caajainfeed.md Support AMP by CA A.J.A. Infeed (#6478) Dec 13, 2016
caprofitx.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
caprofitx.md Support AMP by CA ProFit-X (#3658) Aug 10, 2016
chargeads.js Chargeads AMP integration. (#3290) May 31, 2016
chargeads.md Chargeads AMP integration. (#3290) May 31, 2016
colombia.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
colombia.md Colombia amp ad component (#2949) Apr 25, 2016
contentad.js Content.ad: Improved reliability and security (#6805) Dec 29, 2016
contentad.md Update to documentation (#5316) Sep 29, 2016
criteo.js Criteo: Adding support to RTA tags besides passback (#5463) Oct 12, 2016
criteo.md Criteo: Adding support to RTA tags besides passback (#5463) Oct 12, 2016
custom.md Customad1 (#6491) Dec 8, 2016
distroscale.js Support for DistroScale ads in AMP (#6303) Dec 6, 2016
distroscale.md Support for DistroScale ads in AMP (#6303) Dec 6, 2016
dotandads.js Tighten up forbidden dep tests. (#3155) May 9, 2016
dotandads.md added implementation for dotandads type for amp-ad Feb 3, 2016
eplanning.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
eplanning.md Updated e-planning adserver example (#3241) May 17, 2016
ezoic.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
ezoic.md amp-ad implementation for ezoic (#4285) Aug 10, 2016
f1e.js FlexOneELEPHANT amp-ad support (#4924) Nov 22, 2016
f1e.md FlexOneELEPHANT amp-ad support (#4924) Nov 22, 2016
felmat.js Add felmat support for amp-ad (#6076) Nov 18, 2016
felmat.md Add felmat support for amp-ad (#6076) Nov 18, 2016
flite.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
flite.md Add Flite to amp-ads feature Feb 19, 2016
fusion.js add support for Fusion as server (#6148) Dec 13, 2016
fusion.md add support for Fusion as server (#6148) Dec 13, 2016
genieessp.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
genieessp.md add Geniee SSP support for amp-ad (#3735) Jun 24, 2016
gmossp.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
gmossp.md GMOSSP amp-ad support (#2814) Apr 7, 2016
holder.js AMP integration with Holder (#6024) Nov 9, 2016
holder.md AMP integration with Holder (#6024) Nov 9, 2016
ibillboard.js Ibillboard integration (#5392) Oct 17, 2016
ibillboard.md Ibillboard integration (#5392) Oct 17, 2016
imobile.js Tighten up forbidden dep tests. (#3155) May 9, 2016
imobile.md Intent to Implement MicroAd implementation for amp-ad (#3157) May 12, 2016
improvedigital.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
improvedigital.md Improve Digital AMP integration Mar 25, 2016
industrybrains.md fix typos in documentation and call renderStart (#5644) Nov 2, 2016
inmobi.js Forbid direct style manipulation (#6012) Nov 8, 2016
inmobi.md InMobi Ad extension for AMP (#4886) Sep 16, 2016
ix.js Upgrade amp-ad support for Index Exchange (#6482) Dec 14, 2016
ix.md Upgrade amp-ad support for Index Exchange (#6482) Dec 14, 2016
kargo.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
kargo.md Adding Kargo ad network support to amp-ad (#3918) Jul 7, 2016
kixer.js Adding Kixer ad network to amp-ad (#5690) Oct 24, 2016
kixer.md Adding Kixer ad network to amp-ad (#5690) Oct 24, 2016
ligatus.js Implement 'amp-ad' type: 'ligatus' (#5715) Oct 21, 2016
ligatus.md Implement 'amp-ad' type: 'ligatus' (#5715) Oct 21, 2016
loka.js Support amp-ad for LOKA Research.inc (#4832) Sep 26, 2016
loka.md Support amp-ad for LOKA Research.inc (#4832) Sep 26, 2016
mads.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
mads.md Add support for MADS platform (#4237) Jul 28, 2016
mantis.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
mantis.md 3P: MANTIS Ad Network (#3085) May 6, 2016
mediaimpact.js mediaimpact: (#5420) Oct 11, 2016
mediaimpact.md updated MediaImpact md file (#5655) Oct 20, 2016
medianet.js AMP implementation of Media.net Contextual Monetization (#6479) Dec 13, 2016
medianet.md AMP implementation of Media.net Contextual Monetization (#6479) Dec 13, 2016
mediavine.js Adding Mediavine to amp-ad (#5784) Nov 3, 2016
mediavine.md Adding Mediavine to amp-ad (#5784) Nov 3, 2016
meg.js Turn type checking for 3p code back on. (#5452) Oct 6, 2016
meg.md Meg Ad extension for AMP (#5022) Sep 20, 2016
microad.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
microad.md Add params for microad (#3827) Jul 1, 2016
mixpo.js Add Mixpo support for amp-ad (#5073) Sep 22, 2016
mixpo.md Add Mixpo support for amp-ad (#5073) Sep 22, 2016
nativo.js Using location.href instead of location.origin for nativo.js AD script ( Sep 7, 2016
nativo.md Added NATIVO amp-ad code and integration test (#2888) Jul 6, 2016
nend.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
nend.md Nend amp-ad support. (#3378) Jun 1, 2016
nokta.js Nokta Ad Server is added as an ad type (#5550) Oct 18, 2016
nokta.md Nokta Ad Server is added as an ad type (#5550) Oct 18, 2016
openadstream.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
openadstream.md Update openadstream.md Mar 30, 2016
openx.js Fix Object.assign missing (#4890) Sep 9, 2016
openx.md openx amp ad implementation Mar 21, 2016
plista.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
plista.md #2324 plista is a content-recommendation platform and it supports res… Apr 18, 2016
popin.js Initial support for popIn native ads via amp-ad plugin. (#6122) Dec 6, 2016
popin.md Initial support for popIn native ads via amp-ad plugin. (#6122) Dec 6, 2016
pubmatic.js add no-undef to enforce variables need to be declared and scoped corr… Jun 16, 2016
pubmatic.md Pubmatic Ad plugin (#2654) Apr 11, 2016
pubmine.js Update Pubmine amp-ad to implement render-start api (#6214) Nov 18, 2016
pubmine.md Pubmine integration for amp-ad. (#4603) Aug 26, 2016
pulsepoint.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
pulsepoint.md PulsePoint adapter for AMP. (#3919) Jul 12, 2016
purch.js Purch Ad Support for Amp-Ads (#5464) Oct 17, 2016
purch.md Purch Ad Support for Amp-Ads (#5464) Oct 17, 2016
revcontent.js Revcontent, support render-start (#5234) (#6332) Dec 9, 2016
revcontent.md Revcontent, support render-start (#5234) (#6332) Dec 9, 2016
rubicon.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
rubicon.md Rubicon Adapter, added request type flags and new Doubleclick paramet… May 9, 2016
sharethrough.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
sharethrough.md Add amp-ad type sharethrough (#3036) Apr 29, 2016
smartadserver.js Update Smart AdServer integration (#4990) Sep 15, 2016
smartadserver.md Update Smart AdServer integration (#4990) Sep 15, 2016
smartclip.js Implement smartclip on Google AMP AdNetwork (#5443) Oct 26, 2016
smartclip.md Implement smartclip on Google AMP AdNetwork (#5443) Oct 26, 2016
sortable.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
sortable.md sortable amp ad implementation Mar 25, 2016
sovrn.js Tighten up forbidden dep tests. (#3155) May 9, 2016
sovrn.md Add support for sovrn ad network (#2883) Apr 15, 2016
taboola.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
taboola.md implement taboola ad-type Feb 2, 2016
teads.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
teads.md update teads tag and readme (#3458) Jun 9, 2016
triplelift.js Tighten up forbidden dep tests. (#3155) May 9, 2016
triplelift.md Adding TripleLift to amp-ads Mar 1, 2016
webediads.js Webediads - render-start support (#5462) Oct 13, 2016
webediads.md Webediads - render-start support (#5462) Oct 13, 2016
weborama.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
weborama.md amp-ad type weborama-display (#2833) Apr 12, 2016
widespace.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
widespace.md Widespace integration (#3926) Jul 11, 2016
xlift.js Add Xlift AMP support (#5825) Nov 2, 2016
xlift.md Add Xlift AMP support (#5825) Nov 2, 2016
xrostssp.js Add XrostSSP support for amp-ad (#6435) Dec 9, 2016
xrostssp.md Add XrostSSP support for amp-ad (#6435) Dec 9, 2016
yahoo.js Yahoo amp-ad plugin (#5727) Oct 21, 2016
yahoo.md Yahoo amp-ad plugin (#5727) Oct 21, 2016
yahoojp.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
yahoojp.md Yahoo! JAPAN amp-ad support (#3285) May 24, 2016
yieldbot.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
yieldbot.md feature(amp-ad): yieldbot ad type (#2850) Apr 12, 2016
yieldmo.js Tighten up forbidden dep tests. (#3155) May 9, 2016
yieldmo.md flag yieldmo as renderStartImplemented (#5080) Sep 22, 2016
yieldone.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
yieldone.md YIELD ONE amp-ad support (#4166) Jul 27, 2016
zedo.js Few changes in implementation and documentation (#6437) Dec 9, 2016
zedo.md Few changes in implementation and documentation (#6437) Dec 9, 2016
zergnet.js Migrate usage of checkData() and validateDataExists() to validateData… Aug 22, 2016
zergnet.md Adding support for ZergNet to AMP (#4108) Jul 22, 2016
zucks.js Add Zucks to amp-ad supported adnetwork (#4724) Sep 21, 2016
zucks.md Add Zucks to amp-ad supported adnetwork (#4724) Sep 21, 2016

README.md

Integrating ad networks into AMP

Table of content

Overview

Ads are just another external resource and must play within the same constraints placed on all resources in AMP. We aim to support a large subset of existing ads with little or no changes to how the integrations work. Our long term goal is to further improve the impact of ads on the user experience through changes across the entire vertical client side stack. Although technically feasible, do not use amp-iframe to render display ads. Using amp-iframe for display ads breaks ad clicks and prevents recording viewability information. If you are an ad technology provider looking to integrate with AMP HTML, please also check the general 3P inclusion guidelines and ad service integration guidelines.

Constraints

A summary of constraints placed on external resources such as ads in AMP HTML:

  • Because AMPs are served on HTTPS and ads cannot be proxied, ads must be served over HTTPS.
  • The size of an ad unit must be static. It must be knowable without fetching the ad and it cannot change at runtime except through iframe resizing https://github.com/ampproject/amphtml/issues/728.
  • If placing the ad requires running JavaScript (assumed to be true for 100% of ads served through networks), the ad must be placed on an origin different from the AMP document itself. Reasons include:
    • Improved security.
    • Takes synchronous HTTP requests made by the ad out of the critical rendering path of the primary page.
    • Allows browsers to run the ad in a different process from the primary page (even better security and prevents JS inside the ad to block the main page UI thread).
    • Prevents ads doing less than optimal things to measure user behavior and other interference with the primary page.
  • The AMP runtime may at any moment decide that there are too many iframes on a page and that memory is low. In that case it would unload ads that were previously loaded and are no longer visible. It may later load new ads in the same slot if the user scrolls them back into view.
  • The AMP runtime may decide to set an ad that is currently not visible to display: none to reduce browser layout and compositing cost.

The iframe sandbox

The ad itself is hosted within a document that has an origin different from the primary page.

Available information

We will provide the following information to the ad:

  • window.context.referrer contains the origin of the referrer value of the primary document if available.
  • document.referrer will typically contain the URL of the primary document. This may change in the future (See next value for a more reliable method).
  • window.context.location contains the sanitized Location object of the primary document. This object contains keys like href, origin and other keys common for Location objects. In browsers that support location.ancestorOrigins you can trust that the origin of the location is actually correct (So rogue pages cannot claim they represent an origin they do not actually represent).
  • window.context.canonicalUrl contains the canonical URL of the primary document as defined by its link rel=canonical tag.
  • window.context.sourceUrl contains the source URL of the original AMP document. See details here.
  • window.context.clientId contains a unique id that is persistently the same for a given user and AMP origin site in their current browser until local data is deleted or the value expires (expiration is currently set to 1 year).
    • Ad networks must register their cid scope in the variable clientIdScope in _config.js.
    • Only available on pages that load amp-analytics. The clientId will be null if amp-analytics was not loaded on the given page.
  • window.context.pageViewId contains a relatively low entropy id that is the same for all ads shown on a page.
  • ad viewability
  • window.context.startTime contains the time at which processing of the amp-ad element started.
  • window.context.container contains the ad container extension name if the current ad slot has one as its DOM ancestor. An valid ad container is one of the following AMP extensions: amp-sticky-ad, amp-fx-flying-carpet, amp-lightbox. As they provide non-trivial user experience, ad networks might want to use this info to select their serving strategies.

More information can be provided in a similar fashion if needed (Please file an issue).

Available APIs

  • window.context.renderStart(opt_data) is a method to inform AMP runtime when the ad starts rendering. The ad will then become visible to user. The optional param opt_data is an object of form {width, height} to request an ad resize if the size of the returned ad doesn't match the ad slot. To enable this method, add a line renderStartImplemented=true to the corresponding ad config in _config.js.
  • window.context.noContentAvailable() is a method to inform AMP runtime that the ad slot cannot be filled. The ad slot will then display the fallback content if provided, otherwise try to collapse.
  • window.context.reportRenderedEntityIdentifier() MUST be called by ads, when they know information about which creative was rendered into a particular ad frame and should contain information to allow identifying the creative. Consider including a small string identifying the ad network. This is used by AMP for reporting purposes. The value MUST NOT contain user data or personal identifiable information.

Exceptions to available APIs and information

Depending on the ad server / provider some methods of rendering ads involve a second iframe inside the AMP iframe. In these cases, the iframe sandbox methods and information will be unavailable to the ad. We are working on a creative level API that will enable this information to be accessible in such iframed cases and this README will be updated when that is available. Refer to the documentation for the relevant ad servers / providers (e.g., doubleclick.md) for more details on how to handle such cases.

Ad viewability

Position in viewport

Ads can call the special API window.context.observeIntersection(changesCallback) to receive IntersectionObserver style change records of the ad's intersection with the parent viewport.

The API allows specifying a callback that fires with change records when AMP observes that an ad becomes visible and then while it is visible, changes are reported as they happen.

Example usage:

  window.context.observeIntersection(function(changes) {
    changes.forEach(function(c) {
      console.info('Height of intersection', c.intersectionRect.height);
    });
  });

window.context.observeIntersection returns a function which when called will stop listening for intersection messages.

Example usage:

  var unlisten = window.context.observeIntersection(function(changes) {
    changes.forEach(function(c) {
      console.info('Height of intersection', c.intersectionRect.height);
    });
  });

  // condition to stop listening to intersection messages.
  unlisten();
Initial position

The value window.context.initialIntersection contains the initial intersection record at the time the iframe was created.

Page visibility

AMP documents may be practically invisible without the visibility being reflected by the page visibility API. This is primarily the case when a document is swiped away or being prerendered.

Whether a document is actually being visible can be queried using:

window.context.hidden which is true if the page is not visible as per page visibility API or because the AMP viewer currently does not show it.

Additionally one can observe the amp:visibilitychange on the window object to be notified about changes in visibility.

Ad resizing

Ads can call the special API window.context.requestResize(width, height) to send a resize request.

Once the request is processed the AMP runtime will try to accommodate this request as soon as possible, but it will take into account where the reader is currently reading, whether the scrolling is ongoing and any other UX or performance factors.

Ads can observe whether resize request were successful using the window.context.onResizeSuccess and window.context.onResizeDenied methods.

Example

var unlisten = window.context.onResizeSuccess(function(requestedHeight, requestedWidth) {
  // Hide any overflow elements that were shown.
  // The requestedHeight and requestedWidth arguments may be used to check which size change the request corresponds to.
});

var unlisten = window.context.onResizeDenied(function(requestedHeight, requestedWidth) {
  // Show the overflow element and send a window.context.requestResize(width, height) when the overflow element is clicked.
  // You may use the requestedHeight and requestedWidth to check which size change the request corresponds to.
});

Here are some factors that affect whether the resize will be executed:

  • Whether the resize is triggered by the user action;
  • Whether the resize is requested for a currently active ad;
  • Whether the resize is requested for an ad below the viewport or above the viewport.

Support for multi-size ad requests

Allowing more than a single ad size to fill a slot improves ad server competition. Increased competition gives the publisher better monetization for the same slot, therefore increasing overall revenue earned by the publisher. In order to support multi-size ad requests, AMP accepts an optional data param to window.context.renderStart (details in Available APIs section) which will automatically invoke request resize with the width and height passed. In case the resize is not successful, AMP will horizontally and vertically center align the creative within the space initially reserved for the creative.

Example

// Use the optional param to specify the width and height to request resize.
window.context.renderStart({width: 200, height: 100});

Note that if the creative needs to resize on user interaction, the creative can continue to do that by calling the window.context.requestResize(width, height) API. Details in Ad Resizing.

Optimizing ad performance

JS reuse across iframes

To allow ads to bundle HTTP requests across multiple ad units on the same page the object window.context.master will contain the window object of the iframe being elected master iframe for the current page. The window.context.isMaster property is true when the current frame is the master frame.

The computeInMasterFrame function is designed to make it easy to perform a task only in the master frame and provide the result to all frames. It is also available to custom ad iframes as window.context.computeInMasterFrame. See 3p.js for function signature.

Preconnect and prefetch

Add the JS URLs that an ad always fetches or always connects to (if you know the origin but not the path) to _config.js.

This triggers prefetch/preconnect when the ad is first seen, so that loads are faster when they come into view.

Ad markup

Ads are loaded using a the tag given the type of the ad network and name value pairs of configuration. This is an example for the A9 network:

  <amp-ad width=300 height=250
      type="a9"
      data-aax_size="300x250"
      data-aax_pubname="test123"
      data-aax_src="302">
  </amp-ad>

and another for DoubleClick:

  <amp-ad width=320 height=50
      type="doubleclick"
      json="{…}">
  </amp-ad>

For ad networks that support loading via a single script tag, this form is supported:

  <amp-ad width=300 height=250
      type="adtech"
      src="https://adserver.adtechus.com/addyn/3.0/5280.1/2274008/0/-1/ADTECH;size=300x250;key=plumber;alias=careerbear-ros-middle1;loc=300;;target=_blank;grp=27980912;misc=3767074">
  </amp-ad>

Note, that the network still needs to be whitelisted and provide a prefix to valid URLs. We may add similar support for ad networks that support loading via an iframe tag.

Technically the <amp-ad> tag loads an iframe to a generic bootstrap URL that knows how to render the ad given the parameters to the tag.

1st party cookies

Access to a publishers 1st party cookies may be achieved through a custom ad bootstrap file. See "Running ads from a custom domain" in the ad documentation for details.

If the publisher would like to add custom JavaScript in the remote.html file that wants to read or write to the publisher owned cookies, then the publisher needs to ensure that the remote.html file is hosted on a sub-domain of the publisher URL. e.g. if the publisher hosts a webpage on https://nytimes.com, then the remote file should be hosted on something similar to https://sub-domain.nytimes.com for the custom JavaScript to have the abiity to read or write cookies for nytimes.com.

Developer guidelines for a pull request

Please read through DEVELOPING.md before contributing to this code repository.

Files to change

If you're adding support for a new 3P ad service, changes to the following files are expected:

  • /ads/yournetwork.js - implement the main logic here. This is the code that will be invoked in the 3P iframe once loaded.
  • /ads/yournetwork.md - have your service documented for the publishers to read.
  • /ads/_config.js - add service specific configuration here.
  • /3p/integration.js - register your service here.
  • /extensions/amp-ad/amp-ad.md - add a link that points to your publisher doc.
  • /examples/ads.amp.html - add publisher examples here. Since real ad isn't guaranteed to fill, a consistently displayed fake ad is highly recommended here to help AMP developers confidently identify new bugs.

Verify your examples

To verify the examples that you have put in /examples/ads.amp.html, you will need to start a local gulp web server by running command gulp. Then visit http://localhost:8000/examples/ads.amp.max.html?type=yournetwork in your browser to make sure the examples load ads.

Please consider having the example consistently load a fake ad (with ad targeting disabled). Not only it will be a more confident example for publishers to follow, but also for us to catch any regression bug during our releases.

It's encouraged to have multiple examples to cover different use cases.

Tests

Please make sure your changes pass the tests:

gulp test --watch --nobuild --files=test/functional/{test-ads-config.js,test-integration.js}

If you have non-trivial logic in /ads/yournetwork.js, adding a unit test at /test/functional/ads/test-yournetwork.js is highly recommended.

Lint and type-check

To speed up the review process, please run gulp lint and gulp check-types, then fix errors, if any, before sending out the PR.

Other tips

  • Please consider implementing the render-start and no-content-available APIs (see Available APIs), which helps AMP to provide user a much better ad loading experience.
  • CLA: for anyone who has trouble to pass the automatic CLA check in a pull request, try to follow the guidelines provided by the CLA Bot. Common mistakes are 1) used a different email address in git commit; 2) didn't provide the exact company name in the PR thread.