Amphtml: amp-rewrite-links i2i

Created on 12 May 2017  ·  18Comments  ·  Source: ampproject/amphtml

[Edit: Note the iframe has changed to a CORS request per comments below from @cramforce]

There are several use cases where rewriting the href tags on AMP pages would be useful. These include AMP to AMP linking and affiliate link automation.

This is a tentative proposal for a way to handle this via new amp-rewrite-links component.

The basic model would be similar to amp-ad and amp-analytics a framework to which vendors could add their own code.

<amp-rewrite-links
   type="vendorname"
   data-vendor-specifc-id="1234"
   data-additional-vendor-data="stuff"
></amp-rewrite-links>

Vendors would provide a target url that is loaded in an iframe by the AMP runtime.

Upon load the vendor frame would send a requestLinks message.

The amp-rewrite-links component will respond with links message containing an array of href values from the page (fragment links and amp-bind actions would be ignored). amp-rewrite-links will also begin monitoring for mutations that add or change href values and will send additional links messages with the changed or added values as needed.

When the vendor iframe receives a links message it will respond with a linksDestination message containing an object defining link behavior.

{
  "http://www.example.com/somelink" : {
    "verb": "GET",
    "url": "http://www.someothersite.com/path",
    "target" : "_blank" /* or _top */
  }, 
  "http://www.example.com/anotherlink" : {
    "verb": "POST",
    "url": "http://www.someothersite.com/path"
    "postBody":  "opaque value to send as post body",
    "postHeaders": { /* 
      headers to send with post from whitelist - 
      may include encoding and content-type
    */ }
  }
}

Allowed verbs GET, POST

On a click action the runtime will lookup the href in the responses it's received from the rewrite frame and GET/POST to the new destination as appropriate. Any href not found in the responses is handled as normal.

Any clicks that occur before the frame has responded behave as normal (that is the runtime does not defer clicks for a response)

Questions:

  1. Does this cover all the use cases?
  2. Are there security implications (beyond having to trust your rewrite vendor)?
  3. Allow passing CID and other AMP variables to vendor frame?
  4. Allow publishers to provide their own rewrite frame url or restrict to approved vendors?
INTENT TO IMPLEMENT Soon DiscussioQuestion

All 18 comments

@jpettitt Thanks for the I2I. We'll review it. Normally I'd schedule it for a design review this week, but give I/O we'll probably push it to the following week...

Sounds good. Next week it is.

Why does there need to be a vendor iframe? A CORS request should be fine.

Should define that if the process for resolving links hasn't finished, then the base link is followed.

A CORS request requires vendors to build new endpoints vs an iframe that allows existing infrastructure to be shimmed.

Regarding base linke, agree it says

Any clicks that occur before the frame has responded behave as normal (that is the runtime does not defer clicks for a response)

We can reword that in doc to make it clearer.

Right, our bar for reducing user experience over ease of implementation (by the vendor) is very high.
https://github.com/ampproject/amphtml/blob/master/contributing/DESIGN_PRINCIPLES.md#user-experience--developer-experience--ease-of-implementation

Since these vendors can then use the same endpoint to make their other integrations simpler as well, I think it is good for the web to only allow implementations that have minimal user impact.

Good point. CORS it is.

I have scheduling conflict of next week - can we put this on design review for the 31st? Should be fairly quick.

I will probably be out (moving), but otherwise should work.

I scheduled for 5/31 in #9254.

amp-rewrite-links Preliminary design Incorporating feedback from Design Review

There are several use cases where rewriting the href tags on AMP pages would be useful. These include AMP to AMP linking and affiliate link automation.

This is a tentative proposal for a way to handle this via new amp-rewrite-links component.
The basic model would be similar to amp-list, a CORS endpoint with a defined API

<amp-rewrite-links 
  layout=nodisplay   
  src=”https://example.com/my/rewrite/endpoint”
></amp-rewrite-links>

Vendors would provide a target url that for a CORS endpoint. As with amp-list fetch credentials would be configurable.

After initial page layout and every time the href value of an eligible <a> tag changes amp-rewrite-links would call the endpoint with an application/json post body containing an array of all the http and https href values found on the page. All non http/s urls are ignored including fragment urls.

[
 "http://www.example.com/somelink", 
 "http://www.example.com/anotherlink"
]

The endpoint will respond with a json object containing keys for each url with an object defining link behavior. There will be one key for every supplied url that is to be rewritten. Any link that does not require a rewrite is omitted from the response.

{
  "http://www.example.com/somelink" : { … }, 
  "http://www.example.com/anotherlink" : { … }
}

For each link returned the runtime will return a object defining the rewrite verb, url, target and optionally POST data.

{
  "http://www.example.com/somelink" : {
    "verb": "GET",
    "url": "http://www.someothersite.com/path",
    "target" : "_blank" /* or _top */
  }, 
  "http://www.example.com/anotherlink" : {
    "verb": "POST",
    "url": "http://www.someothersite.com/path"
    "postBody":  "opaque value to send as post body",
    "contentType": /*content type from whitelist */
  }
}

Allowed verbs GET, POST

Allowed content-type values for post (defaults to application/x-www-form-urlencoded)

application/x-www-form-urlencoded
multipart/form-data
text/plain

Allowed targets (defaults to _blank)

_top

The url value of the rewrite must be validated by the amp-runtime to prevent script injection.

On a click action the runtime will lookup the href in the responses it's received from the endpoint and GET/POST to the new destination as appropriate. Any href not found in the responses is handled as normal.

Any clicks that occur before the endpoint has responded behave as normal (that is the runtime does not defer clicks waiting for a response).

Questions:

  1. Does this cover all the use cases?
  2. Are there security implications (beyond having to trust your rewrite vendor)?
  3. Allow passing CID and other AMP variables in the CORS url?
  4. Do we really need to monitor for tag changes or will a single pass be enough?

I don't have strong opinions on your question. Overall this looks good to me. @dvoytenko pinged our security person to take a look and check if we are doing anything bad. My thinking is that while this is a bit weird, it is 10x better than injecting random 3P JS.

Feedback from security was positive.

LGTM for the I2I from my side.

Hi, Tamas from Skimlinks (monetization platform) here. Just wanted to say that we were monitoring this thread for a while now and the implementation outlined above is exactly what we and our million plus publishers were waiting for.

Im not 100% familiar with the AMP project's release cycle, could you please tell me what does "P2: Soon" means?

@lepunk the P2 really doesn't mean much right now. It's going to come down to me finding time to write the code (I too have customers who want it but it's not top of my list right now).

This issue hasn't been updated in awhile. @cramforce Do you have any updates?

@lepunk It's now completely off my radar. If Skimlinks would like to contribute some code I'd be happy to provide design support on the amp side, I just don't have time to write it.

This issue hasn't been updated in awhile. @cramforce Do you have any updates?

Closing as stale. Note that we have amp-skimlinks now too. Please reopen as desired.

Was this page helpful?
0 / 5 - 0 ratings