AMP

AMP Conf 2020: Return to NYC

AMP Conf
AMP Conf 2019 in Tokyo

Last year over 500 of us gathered in Tokyo to share the latest AMP news and learn from some of the thousands of developers engaged with the open source project. A lot has happened in the world of AMP since then, including AMP joining the OpenJS Foundation, our release for general availability of <amp-script>, Adobe Campaign launching support for AMP For Email, and many other exciting developments. We’ve seen amazing growth in the AMP community as developers around the world continue to build beautiful, performant sites, all while using AMP as a way to stay productive and innovative.

AMP Conf returns to NYC!

We are thrilled to invite you to join us at the next AMP Conf, being held in New York City on June 16 and 17. We are so excited to be returning to the city where AMP Conf got its start, and can’t wait to see you there. Come to learn about the latest ways the AMP community is working to make the web better for everyone – publishers, platforms, advertisers, creators, and of course, users. You’ll hear from those working on contributing to AMP, those using the format, and the committees who manage AMP’s governance. 

We also want to continue the tradition of including broader community voices by inviting you to submit ideas for talks. We want to hear about the most interesting things you’ve done with AMP, how AMP has increased your team’s productivity, how you’ve approached building AMP pages, or how you’ve innovated with AMP Stories, AMP For Email, and AMP Ads. Stay tuned for more information and a form to submit ideas for talks.

We will be releasing applications for spots at AMP Conf in the coming month, but in the meantime click here to save the date on your calendar. We’ll also share more details soon regarding a limited number of travel scholarships for those who may need travel support, especially those from underrepresented communities.

If you’re unable to attend in person, we’ll be recording and live streaming all of the talks, so subscribe to the AMP YouTube channel to catch those videos in the meantime.

Stay tuned for details on registration and the talk agenda as we get closer to the event! We look forward to seeing many of you in New York City later this year! 

Posted by Alex Durán, AMP Project Marketing Lead at Google 

In search of the amp.dev search

Websites

Editor’s Note: the following guest post was written by Thorsten Harders and Sebil Satici, Developers at Jung von Matt.

Amp.dev offers a lot of resources that make it easier to get started and build with AMP: case studies, details on how each component works, guides with best practices, step-by-step tutorials and plenty of executable code examples. In fact, it offers so many resources that we needed a way for developers to quickly discover and reach all that existing content. We wanted to do so by making all of our content searchable directly on the site. This article walks through the steps we took to implement search on amp.dev.

https://blog.amp.dev/wp-content/uploads/2020/02/ezgif.com-gif-to-mp4.mp4

TL;DR: The new amp.dev search is built using <amp-lightbox>, <amp-list>, <amp-autocomplete>, <amp-mustache> and of course <amp-bind> to glue them all together. It uses a custom API that is backed by Google custom search and it uses Service Worker functionalities to cache the latest search query and results.

Built with AMP components

We had three goals when building the amp.dev search functionality:

  1. The search should be accessible in its own layer from all pages.
  2. The search should be optimized for finding AMP components, as these are core to the AMP developer experience.
  3. The search should be implemented using valid AMP functionalities.

Hide and show the search layer (with amp-lightbox)

Looking around the web you’ll see many different types of search functions. Some are just plain input fields while others expand and collapse with fancy animations. Some trigger a page-load to paginated result pages, others asynchronously display results. Some auto-suggest search terms, others don’t. For amp.dev we wanted to combine the best of those approaches to come up with a solution that manages to stay out of the user’s way as much as possible while at the same time being quickly accessible. Therefore, we decided to encapsulate the whole search in a fullscreen layer to:

  • suggest interesting articles to users (e.g new guides or components that have been published) no matter what page the user is on
  • avoid distracting the user with other elements on the page
  • quickly display the search results inline without having to load an extra results page

To accomplish our needs we have decided to continue with <amp-lightbox>. It makes it easy for us to hide and show the search layer while offering us helpful actions and events we could use for the integration in our AMP frontend.

Adding seamless interaction

From a user experience perspective, it was particularly important to us that the user achieves a seamless transition between entering the search query and seeing the result. When the user opens the search layer, the input field is automatically focused and the user can start typing right away. When the search layer is closed, we focus the search toggle again, so that keyboard users can continue in the same position as before.

We implemented this feature using the <amp-lightbox> open and close events in combination with the global focus action:

<amp-lightbox layout="nodisplay"
      on="lightboxOpen:searchInput.focus;
          lightboxClose:searchTriggerOpen.focus"
      scrollable>

Listing the search results (with amp-list and amp-mustache)

For displaying the search results on the page, we use the <amp-list> component as it has paging and infinite scroll already built-in – exactly what you need when listing search results.  The actual search is implemented server-side and can be accessed via an API endpoint /search/do which returns a JSON object similar to this:

{
  "result": {
    "pageCount": 10,
    "pages": [
      {
        "title": "Some title",
        "description": "Description",
        "url": "http://amp.dev/some/link"
      },
      ...
    ]
  },
  "nextUrl": "/search/do?q=amp&page=2"
}

We use amp-bind to update the full search URL in our  <amp-list>, by binding the [src] attribute to the input query. To enable infinite scrolling, we set the load-more attribute and for a cleaner reload experience when triggering subsequent searches, we set the reset-on-refresh attribute. In the <amp-mustache> template we use the data from the result object to render the list dynamically. Here is the code:

<amp-list id="searchList"
          src="/search/initial-items"
          [src]="query ? '/search/initial-items : '/search/do?q=' + 
encodeURIComponent(query)"
          binding="no"
          items="."
          height="80vh"
          layout="fixed-height"
          load-more="auto"
          load-more-bookmark="nextUrl"
          reset-on-refresh
          single-item>
  <template type="amp-mustache">
    <div class="search-result-list">
      {{#result.pages}}
      <a href="{{url}}">
        <h4>{{title}}</h4>
        <p>{{description}}</p>
      </a>
      {{/result.pages}}
    </div>
  </template>
</amp-list>

Suggest what matters (with amp-autocomplete)

https://blog.amp.dev/wp-content/uploads/2020/02/ezgif.com-gif-to-mp4-1.mp4

According to our analytics data, developers most often visit amp.dev to access AMP component documentation and samples. That’s why we wanted to make these as easy to discover as possible. With <amp-autocomplete>, AMP offers an out-of-the-box solution for implementing auto-suggestions. The goal is to auto-suggest all available AMP components. The static datasource is provided by the /search/autosuggest endpoint and the autocomplete generates suggestions client-side using the filter="substring" designation.

<amp-autocomplete filter="substring"
                  min-characters="1"
                  on="select:AMP.setState({    query: event.value })"
                  submit-on-enter="false"
                  src="/search/autosuggest"
>
    <input placeholder="What are you looking for?">
</amp-autocomplete>

Executing the search (with amp-form)

Users can trigger the search by selecting one of the auto-suggested options or submitting the form. To execute the actual search request we are using the state query as a URL parameter.

<amp-list [src]="'/search/do?q=' + encodeURIComponent(query) + '&locale=en'">

Based on the on action in the amp-autocomplete, the query is updated (and amp-list rerenders) both when the form submits and when autocomplete emits a select event.

<form action-xhr="/search/echo"
      on="submit:
          AMP.setState({ query: queryInput }),
          searchResult.focus,
          searchList.changeToLayoutContainer"
      method="POST" target="_top">
  <amp-autocomplete filter="substring"
                    min-characters="1"
                    on="select:AMP.setState({ query: event.value })"
                    submit-on-enter="false"
                    src="/search/autosuggest"
  >
    <input id="searchInput"
           placeholder="What are you looking for?"
           on="input-throttled:AMP.setState({ queryInput: event.value })"
    >
    <button disabled [disabled]="!queryInput">Search</button>
  </amp-autocomplete>
</form>

When the form is submitted we also focus the search result container to let the keyboard navigation start directly with the first entry. Additionally, we call changeToLayoutContainer of the <amp-list> to ensure the list’s height will change according to the content and can get smaller. Because in our case the result of the form submit event is not needed, we simply point to an echo action. Sidenote: this won’t be needed in the future as it’s soon going to be possible to use `amp-autocomplete` without  a form.

Caching previous search results via Service Worker

After we launched the first version of the search we received a related feature request fairly quickly: keep showing the results for the latest search query, even when the user navigates to another page.

To achieve this, we built upon AMP’s one-line Service Worker amp-sw which offers basic PWA functionalities like caching and offline pages. We extended it to store the latest search query and the corresponding search results.

When a search is started, we display the previous search query and its results. Otherwise, we will display a list of suggested articles. On page load, we initialize an amp-state object from a server endpoint /search/latest-query which populates the search input field and the search results:

// search.html
<amp-state id="query" src="/search/latest-query"></amp-state>

<amp-list src="/search/initial-items"
          [src]="query ? '/search/initial-items : '/search/do?q=' + encodeURIComponent(query)"
...
</amp-list>

The trick is: this server-endpoint does not exist. The magic happens in the Service Worker which intercepts the route and creates a new response with the cached search query and search results from the user’s last search request and sends it back to the page instead of loading the original response from the network.

To save the latest search query, we grab the query parameter from the requested URL with a regular expression and store it in a newly created response object in our cache.

Then the route handler checks if there is an entry in the cache that matches the search request. If there is the results are returned from the cache immediately. Otherwise, the request falls through to the server and then gets cached for the following calls.

// serviceworker.js
async function searchDoRequestHandler(url, request) {
  const searchQuery = decodeURIComponent(url.search.match(/q=([^&]+)/)[1]);
  const cache = await caches.open(SEARCH_CACHE_NAME);


  cache.put(SEARCH_LATEST_QUERY_PATH, new Response(`"${searchQuery}"`));

  let response = await cache.match(request);
  if (response) return response;

  response = await fetch(request);
  if (response.status == 200) {
    cache.delete(request, {
      ignoreSearch: true,
    });
    cache.put(request, response.clone());
  }

  return response;
}

This way when the user opens the search layer on another page, they automatically receive their previous search results back and can continue where they left off.

Here you can see how a handler function is registered:

// serviceworker.js
self.addEventListener('fetch', (event) => {
  const requestUrl = new URL(event.request.url);
  if (requestUrl.pathname === '/search/do') {
    event.respondWith(searchDoRequestHandler(requestUrl, event.request));
  }
});

Intercepting and dynamically changing requests with the help of the Service Worker API is a neat way whenever you want to personalize data used by AMP components that load data from remote endpoints like <amp-state> or <amp-list> et al. Just like it helped us to enhance the user experience for the search by caching the user’s latest search query.

Conclusion

With the implementation of a search function within amp.dev, we accomplished our goal of allowing users to precisely navigate the content of the site in an intuitive and efficient manner. For even better user experience, we are also caching previous search results with Service Worker functionalities.

The cool thing about this is that we integrated the search without a single line of JavaScript (except the Service Worker part). Just by making use of AMP’s existing components we could integrate useful features like auto-suggestion and infinite scrolling, which would be quite challenging to implement otherwise!

Written by Thorsten Harders and Sebil Satici, Developers at Jung von Matt

SEO for AMP Stories

Stories

AMP Stories are a new, exciting medium for storytelling on the web. The format is based on the same concept as familiar Stories features in popular social networking apps but intended for more general purpose content from “how to apply lip gloss the right way” to a “travel guide through the Himalayas”. Importantly, AMP Stories are just web pages. They have a URL on your web server, they are linkable, and they can link out to other web pages. With that the biggest takeaway for SEO of Stories is:

Do all the SEO things you would do for any other page on your website. If it helps rank your non-Story pages, it’ll probably help the Stories as well.

In particular, just like other pages on your site, make sure your Stories are linked from within your website so that your users and bots can actually discover them. If you are using a sitemap, make sure to include your Stories in that sitemap. If you are posting your regular web pages to social media, post your Stories as well. We could go on here, but the gist really comes down to: Follow the best practices you’re already applying to the rest of your website.

Stories specific SEO tactics

Given the relative newness of this format on the web and its unique characteristics, there are SEO tactics specific to Stories. These tactics aren’t comprehensive and should be augmented with all the standard SEO work being done for your web pages that’s described above.

Metadata

AMP Stories have a built-in mechanism to attach metadata to a Story. Make sure all your Stories follow these metadata guidelines. This ensures maximum compatibility with search engines and discovery features that take advantage of that metadata.

Additionally, make sure you include all the title, description, schema.org, OGP, Twitter card, etc. markup you would include in any other web page.

Linking to Stories

We recommend deeply integrating Stories into your website such as linking them from your homepage or category pages where applicable. E.g. if your Story is about a travel destination and you have a page that lists all your travel articles, then also link the Stories on that category page. An additional special landing page like www.example.com/stories (which would then be linked from key pages like your homepage) might also make sense.

Links from within your site and to other websites are a critical component of how the web works and optimizing for discoverability. As Stories are web pages themselves, this is also true for them.

URL format

There is no need to indicate in the URL of a Story that it is using the AMP Stories format. Ideally your Stories are integrated into a wider URL strategy. For example, if your “New York Travel” articles are using a format like “/new-york/travel/title-of-article.html” then consider using the exact same directory structure and URL format for your Stories.

Page attachments

Page attachments can be used to present additional information in “classic article form” alongside your Story. This can be useful to provide extra detail, deep dives, or onward journeys for the content presented in your Story.

Image descriptions

While this best practice technically applies to all web pages, we have seen folks omit “alt” text for images in Stories. We strongly recommend adding meaningful “alt” text where appropriate to optimize for accessibility and indexability of your content.

Video subtitles

Consider providing subtitles and/or captions for the videos in your Stories.

Video-only Stories

We recommend that you take full advantage of semantic HTML to build up your story. However, some tools designed for the social media use case may instead export a story such that each slide is represented as a video file that bakes in all the text into the video. In this case it is recommended to add the precise text displayed inside of the video as a “title” attribute on the amp-video element. Again, only do this if you absolutely cannot use semantic markup in your Stories generation.

Desktop

While the Stories format is traditionally associated with mobile consumption, AMP Stories also work on desktop with optional support for landscape displays. This means that your Stories can also appear in desktop search results without any extra work.

AMP’s canonical-pairing is not supported

Although AMP Stories are created using the AMP framework, AMP Stories should be self-canonical. That is, the <link rel=”amphtml”..> pairing that is frequently used by AMP Pages is not available for Stories. Make sure to AMP-validate your Web Stories.

The Secret of SEO

As a final reminder: Content is king! Like any web page, providing high quality content that is useful and interesting to your users is and will always be the most important “SEO tactic” that cannot be ignored and takes precedence above all else. Include a complete narrative and follow these best practices to take advantage of the unique characteristics of the format to keep the users engaged. 

Summary

SEO for Stories is like SEO for any other web page. Your SEO skills should translate 1:1 to Stories. A limited number of Stories-specific SEO best practices exist and they are documented in this blog post. Finally, remember to include high quality content and good luck optimizing your Stories!

Posted by Flavio Palandri Antonelli, Software Engineer at Google

Behind the Scenes: Deploying the AMP Runtime

Developer Experience

One of the main benefits of using AMP is its evergreen release. Today, web developers and engineering teams can get the best of what AMP has to offer every week without being burdened by dependency management. 

Over the past few months, the Infrastructure Working Group has been working hard to improve the way AMP releases its runtime and components. The improvements are based on the following feedback:

  • Some development teams prefer a slower release cadence so they don’t have to run Quality Assurance (QA) for their website every week.
  • Existing documentation for AMP releases can sometimes be incomplete or confusing.
  • It’s essential to be able to detect potentially breaking changes before they reach the majority of end-users.
  • Some partners would like to be able to self-host the AMP runtime and components during development instead of having to fetch them from cdn.ampproject.org.

The goal of this blog post is to help the reader understand how AMP releases work today, and to learn about upcoming improvements (like updated release channel names, the LTS and Nightly channels, and the ability to self-host AMP on origin URLs).

Understanding AMP Releases

A new version of the AMP runtime is released each week. In order to create confidence in the fact that publishers’ websites will look and behave the same, releases are provided via multiple channels. The main release channels are called Stable, Beta, and Experimental. They serve different purposes, and are seen by different population sizes. In addition, we’re introducing two more channels called LTS and Nightly to further aid in testing and maintenance. Here is a brief description of each channel.  

Stable Channel

This is the main production-ready release channel for the AMP runtime, and is used by the vast majority of AMP documents. When a change is submitted to the AMP codebase, it goes through multiple layers of testing and verification via other channels before becoming part of the stable channel.

Beta Channel

The beta channel is an accurate representation of the upcoming stable channel release. Developers and QA teams may opt in to the beta channel in order to verify their websites against the latest changes to the AMP runtime. This can be done by opening the AMP experiments page in a browser and activating the “AMP Beta Channel”.

Note: Opting in to the beta channel will only affect the version of the AMP JS libraries used in your browser. There is no way to force visitors to your website to receive the beta channel version of AMP.

The beta channel may be less reliable than the stable channel, and may contain features not yet available to all users. It is intended for:

  • Trying out a new AMP feature that will be released the following week.
  • Performing QA to verify that a website is compatible with the next version of AMP.

Experimental Channel

Some new AMP features can take multiple weeks to develop and test. As a result, they are hidden behind experimental flags that are turned off in the beta and stable channels. The experimental channel provides developers and QA teams with a way to try out and test new features. This can be done by opening the AMP experiments page in a browser and activating the “AMP Experimental Channel”.

Note: Opting in to the experimental channel will only affect the version of the AMP JS libraries used in your browser. There is no way to force visitors to your website to receive the experimental channel version of AMP.

The difference between the experimental and beta channels is the fact that some features that are in development may be available in experimental, but turned off in beta. If a feature is considered ready for use, its flag is turned on, making it visible in the beta channel, and eventually, the stable channel. Depending on the feature, this could take days, weeks, or even months.

Long Term Stable (LTS) Channel

A recurring request from developer teams has been for an AMP release channel with longer intervals between versions in order to allow for a longer QA cycle than the current weekly cycle.

The newly created Long Term Stable (LTS) release channel solves this problem. Approximately monthly, a recent stable channel release is promoted to the LTS channel.

It’s important to note that the LTS channel is not recommended for all AMP publishers. It is provided for those who wish to test their websites less frequently, and are okay with waiting a few weeks before using new features. Publishers may opt to use the LTS channel for specific pages on their website. Webpages using the LTS channel will get the same cache benefits as with the stable channel.

Unlike the beta and experimental channels which individuals can opt in to by setting a browser cookie, the LTS channel is served to all users of a webpage when the publisher opts to use it for that page.
A new LTS version is made available on the second Monday of each month by promoting the previous week’s stable channel release. The schedule for the LTS channel can be found here.

Using the LTS Channel for a Webpage:

Here’s an example of a webpage that uses the stable channel:

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

To use the LTS channel instead, simply change the “src” attribute for the runtime and extension scripts as follows, by adding “lts/” to the URL:

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

Note: You should ensure that the AMP runtime and extension scripts you are using are on the same channel to make sure your AMP document is valid. For example, using v0.js from the LTS channel and amp-carousel-0.1.js from the stable channel will result in a validation error.

Nightly Channel

In order to increase confidence in the quality of upcoming AMP releases, we will soon automatically generate nightly builds of the AMP runtime, and make them available via a new Nightly channel. This channel will help reduce error rates, improve runtime performance, and ensure overall code quality. Code from the nightly channel will eventually make it into the beta / experimental, stable, and LTS channels. Once it is introduced, developers will be able to opt in to the Nightly channel in the same way that they can opt in to experimental or beta, as described above.

Note: We do not encourage developers to opt in to the nightly channel unless they wish to test changes daily, as it is less stable than the beta, experimental, and stable channels.

Release Schedule

The section above went over all the existing and upcoming release channels. Let us now follow the journey taken by a piece of code from when it is submitted to the open source repository via a pull request, to when it makes its way through the various release channels.

Suppose a piece of code is merged to the open source repository on the 8th of a given month (N). Since this happens to be a weekday, the following nightly build (the 9th) will include the code. After a few days of testing, on Tuesday the following week (the 16th), users can see the code by opting in to the beta or experimental channels. Assuming no issues are discovered, the code will make it to the stable channel the following Tuesday (the 23rd). Finally, on the second Monday of the following month (the 16th of month N+1), the same stable channel release will become the new LTS channel release.

You can read more about AMP’s release channels and schedule at the project’s release schedule page. You can also visualize the process by which new code is merged into the amphtml GitHub repository progresses through time to reach publishers, developers, and end-users.

A New Way to Self-host the AMP Runtime

We are currently working on making it possible for website owners to self-host the AMP runtime, without breaking AMP validity. The benefits are:

  • Independence: The AMP runtime and components no longer need to be loaded from https://cdn.ampproject.org for AMP pages served from an origin URL.
  • Control: Websites can align the roll-out of a new AMP version with their own QA. They can also rollback to a different version of the AMP runtime whenever the need arises.
  • Performance: Faster page load and TTI by avoiding an additional HTTPs connection.

The goal is to allow publishers to link to a self-hosted version of the AMP runtime without breaking AMP validity. This means the following will be valid AMP:

<!DOCTYPE html><html amp transformed="self;v=1">
<head>
  <script async src="https://example.com/amp/v0.js"></script>
  <script
   async custom-element="amp-bind"
   src="https://example.com/amp/v0/amp-bind-0.1.js"
  ></script>  
   ...

Note: In order to preserve user privacy, AMP Caches will not support runtime self-hosting and instead will rewrite links to the cache hosted scripts. 

The plan is to launch AMP runtime self-hosting later this year and you can follow the implementation via the intent-to-implement and the design doc

* * *

With all these changes, we hope AMP releases are easier to understand, adopt, test, and deploy. Our thanks go out to you, the AMP development community, for your work and feedback. As always, please let us know if you have any issues or feature requests.

Posted by Naina Raisinghani and Raghu Simha, AMP Project

Helping to fund our open-source dependencies

Community

As has now become a yearly custom, we want to update you all on our effort to help sustainable development open-source projects that AMP depends on.

It is increasingly clear that relying on people’s volunteered free time to drive mission critical open source software is not a sustainable mode of operation. As a community we need to find new ways to fund the valuable work on such projects. We strive to provide at least some financial support to projects that we directly depend on and that are accepting support.

Total funding: $117,100 (2019 $58,700)

The projects we supported are:

We’re super glad we’ve been able to support these amazing projects and are looking forward to doing even more in 2020!

Posted by Malte Ubl, Member of the AMP Project Technical Steering Committee

Cookie classification on AMP

Web Standards

Posted by Katharina Familia Almonte, Global Product Lead at Google on the AMP Project

Last year, Chrome announced its plans to introduce a cookie classification scheme as part of its ongoing effort to improve privacy and security across the web, which is expected to take effect with Chrome 80 in February 2020. Mozilla has affirmed their support of the new cookie classification model with their intent to implement the SameSite=None; Secure requirements for cross-site cookies in Firefox. Microsoft has announced plans to begin implementing the model starting as an experiment as soon as Microsoft Edge 80.

The AMP team is committed to protecting user privacy and this blogpost will explain how you can support greater transparency and user choice with the upcoming browser changes, while also maintaining a good user experience with AMP. With Chrome 80 expected to launch in February, this blogpost will focus on Chrome’s changes specifically.

Chrome’s new cookie settings explained

Chrome’s new secure-by-default model assumes that all cookies should be protected from external access unless otherwise specified. Developers must use a new cookie setting, SameSite=None, to designate cookies for cross-site access, and an additional Secure attribute so cross-site cookies can only be accessed over HTTPS connections. Chrome will treat cookies that have no declared SameSite value as SameSite=Lax cookies. Only cookies with the SameSite=None; Secure setting will be available for external access, provided they are being accessed from secure connections. For more detail on the new model, read this developer blog post.

Who’s affected

If your site needs to access your own first party cookies on AMP pages rendered in the AMP Cache, we recommend assessing carefully whether the upcoming browser changes will impact your user experience. This could be the case, for instance, when users transition from the AMP cache to the origin domain and a paywall, login state, measurement or shopping cart functionality relies on first party cookie access. There are two different solutions you could employ, but which one is best for your site will depend on your specific use cases and can change over time.  

Designating cookies for cross-site access

One solution for AMP publishers affected by Chrome’s cookie classification changes, is to set your first party cookies on AMP pages to SameSite=None; Secure. This will designate the first party cookies  for cross-site access and avoid disruptions in user experience:

Set-Cookie: widget_session=abc123; SameSite=None; Secure

The benefit of this approach is that it is the easier one to implement, but if browsers proceed to offer users fine-grained controls to manage cookies accessed by a single site separately from cookies accessed across multiple sites, there is a higher risk that users will clear your first party cookies on cached AMP pages since they will be marked for cross-site access.

Signed Exchange offers help

Alternatively, publishers can use Signed Exchange to achieve a state where first party cookies are treated as such on AMP pages rendered in the AMP Cache. Signed Exchange is an emerging technology that can be used to attribute the page’s URL to the original publisher domain, even when the page is delivered via the AMP cache with all of the loading speed benefits it provides (see blog post and guide). The benefit of Signed Exchange here is that when browsers start preventing cookies from external access unless they are specified otherwise, Signed Exchange will ensure that your first party cookies don’t require designation on pages rendered in the AMP Cache. But Signed Exchange does not currently address all use cases as it is not supported in the Top stories carousel at the time of writing.

Summary

In summary, Chrome is planning to introduce its new SameSite=None; Secure cookie settings in February. To ensure an optimal user experience on pages in the AMP cache that need to access first party cookies, we recommend publishers designate cookies for cross-site access via these new settings or implement Signed Exchange. We hope this blog post helps you maintain a good user experience while also supporting the path to greater privacy controls for users, as browsers start adopting the new cookie classification model. For more details on how to use and test Chrome’s SameSite cookies check out the guide on web.dev and the tips in the Chromium SameSite Updates.

CCPA support in AMP

Web Standards

Posted by Jeffrey Jose, Product Manager at Google on the AMP Project

The California Consumer Privacy Act (CCPA) is a new data privacy law that establishes various rights for California state residents. The law applies to companies that do business in California and meet one of several criteria related to revenue, data processing, and other factors. 

Updates to the AMP consent framework

Based on the feedback we heard from publishers, we’ve updated the AMP consent framework to obtain the consent publishers might deem necessary for CCPA compliance. With these new updates, publishers can include multiple consent prompts and trigger the right prompt based on the location of the user.

Consent across multiple surfaces

Publishers who wish to keep user consent in sync between multiple surfaces can store the user’s consent on the server-side and expose the information to <amp-consent> via the checkConsentHref attribute. You can configure AMP to check your endpoint first and the response determines whether a user-consent prompt is displayed or not. Additionally, the previously obtained user consent can be passed from the server to the ads and analytics vendors configured on the page.

Support in AMP Stories

For AMP Stories, publishers can create links to their CCPA opt-out page within a story to collect user consent. 

We’ve also updated our reference docs and amp.dev with sample codes to illustrate sample scenarios.

Looking ahead

To make development easier, we plan to extend <amp-geo> in the future by providing US state level detections of users. As always, we invite you to submit new ideas by filing an issue. If you’re a vendor who wants to customize how your AMP extensions behave based on user controls, please get started by following our contribution guidelines.

AMP 2019 Decoded: Thank You for an Incredible Year

Websites

2019 was a big hit for AMP. We continued to grow our community and create excellent experiences across websites, email, stories and ads. So let’s flashback to the beginning of this year and recap all the milestones we accomplished together.  Watch the video and read below:

Next.js for AMP 

Building AMP pages through React server-side rendering has gained enough momentum for us to realize we needed to add to our capabilities to support this use-case. That’s why we integrated with Next.js, one of the most popular frameworks for React. Fun fact: nextjs.org is built entirely with AMP!

amp-script

The game-changer <amp-script> finally hit your screens this year. This highly anticipated component enables you to add custom JavaScript to your AMP pages, share code across AMP and non-AMP pages, and build things that were not possible before.

OpenJS foundation welcomes AMP 

We revealed what’s next for our open governance model by announcing our decision to join the OpenJS Foundation. Its mission aligns with ours, and it’ll magnify diverse voices in tech and support our efforts to create a fairer web. 

AMP in your inbox 

Gmail launched support for AMP for email, bringing our user-first experience to an inbox near you. Email senders can now create frictionless experiences and interactive content to boost engagement. The AMP for email spec also has engagement from other major email providers like Outlook and Yahoo Mail, and we are looking forward to reshaping the email ecosystem together. 

The new component is also available on Mail.ru, and early adopters are already celebrating great results. OYO, India’s largest hospitality company, saw a 60% uplift in conversions when testing AMP for email. 

Arigato for making AMP Conf a success  

Our team met nearly 500 of you in Tokyo at our third annual #AMPConf. In addition to product announcements, we also launched a completely redesigned amp.dev, one website for all of our code samples, templates, and documentation. AMPConf2020 is already in the making, so stay tuned to hear where we will be taking the event next.

AMP Contributors Summit in the Big Apple 

In early October we caught up with around a hundred contributors in New York at the annual #AMPCS2019 to discuss new features for AMP. It wasn’t just talk, we hosted breakout sessions where we worked together to improve our projects, and knocked some AMP socks off in the process. 

A strong community

Nearly 1,000 people have contributed code to AMP and are helping us design a faster, better web for all. This year alone, 341 contributors made over 18,300 contributions across all AMP project repositories. 

The People Behind the Code

The community plays a massive role in making AMP great; it’s where we share what we know and learn what we don’t. So we launched the ‘People Behind the Code‘ series to understand how community members use AMP in real life to make a difference. 

19 new Roadshows under our belt 

AMP hit the road 19 times this year, taking our Roadshows around the globe. From Johannesburg to Seoul, 1,600 of you came out to see what AMP is all about. 

The Roadshows are designed to help developers build full-fledged AMP websites with confidence. So we deep-dive into the key four pillars: design, interactivity, DevOps and monetization, to make sure you have everything you need to excel. 

If you want to see where we will be going in 2020, head over to our AMP Roadshow page to find out. Can’t see your city on the list? Let us know, we’re always looking for new places to visit, or host your own event. We’ll provide you with all the material – all you need to do is to show up!

2020 vision 

It’s been a remarkable year. Thank you for your creativity and commitment to creating a faster, user-first web for all. We’re excited to see what’s next for AMP, and look forward to continuing our work together in the new year. To stay in the loop about all of AMP’s projects and see our 2020 vision, sign up for our newsletter. 

Posted by Alex Durán, AMP Project Marketing at Google

Our 2019 Contributions to Web Platform Interoperability

Websites

Editor’s Note: the following post was written by Frédéric Wang, Partner at Igalia

For the third year in a row, the AMP Project has worked with Igalia to address bug reports and enhancement requests from the Web community. Typical tasks include bug triaging, debugging and analysis, writing tests, landing patches, and discussions with the different actors of the Web platform. This has not only been instrumental to significantly speed up the goals of the AMP project, but has also been generally beneficial to all the developers and users of the Web platform.

This blog post describes our activities for this year, focusing on WebKit/iOS bugs and features. However, our Web platform interoperability effort occasionally extends to other browser communities and standardization groups as well.

Resize Observer

Intersection Observer shipped in iOS 12.2 thanks to Google Engineer Ali Juma. This is a new JavaScript API to asynchronously watch changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport.

Resize Observer is a similar API  which we implemented earlier this year under a preference flag. This JavaScript API allows Web developers to asynchronously observe when an element is resized, regardless of why. It is available in iOS 13 beta and the corresponding preference flag has been turned on by default in trunk, so we expect this feature to be available in the iOS 13 release. (Update 01/28/2020: ResizeObserver is now part of Safari Technology Preview)

Scrolling

Apple took over the task we started last year to make <iframe> elements scrollable and this behavior is now enabled by default in the latest iOS 13 version. Other bug fixes involving scrollable elements landed for scroll-snap-align, scrollability after resize find-in-page indicator after scroll as well as for various iOS 13 regressions related to scroll flickering and jittering.

Enhancements have been implemented for the ScrollIntoViewOptions parameter of scroll APIs. Support for logical scroll alignment is shipped in iOS 13. We also continued our efforts to support the scroll-behavior IDL parameter and CSS property and we expect to complete this in the next semester. While working on this, we also detected and fixed Chrome bugs related to the scrollIntoView() method, including cases when a scrollbar is present or when the scroller uses a non-default writing mode.

An old browser interoperability issue for users relates to inconsistent values of scrollLeft, scrollTop and similar APIs and one of our important achievements has been to ensure more reliable and standard behavior happens when setting or getting scroll coordinates. We introduced an option to make Chrome use standard values in non-default writing modes and plan to ship it, after ensuring that it won’t cause serious breakage. Similarly, Apple decided to enable our 2018 changes for the viewport scroller on all WebKit ports.

Besides usual bug fixes, we began implementing other interesting scrolling features, including overscroll customization and overscroll-behavior which are powerful APIs for web developers to control what happens when a scroller reaches its boundaries. We expect more progress on this next year.

Resource Loading

Another exciting goal is to give more power to Web authors to control loading behavior. In particular, this allows the ability to control privacy and optimize page layout.

The referrerpolicy attribute has been implemented to specify how much referrer information should be included within the requests associated to an HTML element loading resources. This is only implemented for the <iframe> and <script> elements and is available in iOS 13 under an experimental feature flag. We will continue to talk to Apple to see when this can be enabled by default or implemented for other elements.

The imagesrcset and imagesizes attributes on <link rel=preload> have also been implemented and are available in iOS 13 under an experimental feature flag. These attributes give the possibility to preload a responsive image represented by an <img> element with relevant sizes and srcset attributes and optimize the selection of the appropriate size for the user device.

We also started to submit patches to support the lazyload attribute on the <img> and <iframe> elements. These attributes enable Web authors to indicate whether it is a good idea to lazily load the element content (e.g. if they are not visible in the viewport until the user scrolls to them) or if their content should instead be loaded right away. These hints are very helpful for browsers to optimize loading of resources.

Finally, we made an experimental support for the intrinsic size attribute in WebKit. This proposal is intended to help browsers to determine aspect ratio or size of an image before its content is actually loaded, in order to avoid extra post-load reflow. This proposal has been superseded by a pure CSS-based approach addressing the same use case. Our experiment was useful for discussions among browser vendors and within the CSS WG and we plan to rewrite our patch to instead implement the CSS-based approach in WebKit.

Conclusion

Collaboration between the AMP project and Igalia to advance the state of the Web Platform has been very successful. There are several pending tasks and new ideas to work on so we look forward to continuing with this effort next year!

From Static to Interactive: Adobe Campaign Brings Email to Life with AMP for Email

Email

Adobe drives innovation as one of the firsts to deliver this modern app functionality from Google.

Editor’s Note: the following guest post was written by Sunil Menon and was originally featured on the Adobe Blog

Email continues to play a major role both in our professional and personal lives. In fact, according to Adobe’s annual Consumer Email Survey, Americans spend more than five hours a day checking their emails. With consumers spending so much time in their inbox, email has become an essential channel for brands to engage with their customers. Our survey also revealed that 60% of consumers prefer to receive brand offers via email, yet consumers only find a quarter of the emails they receive interesting enough to open.  

If email content is static, it can become out-of-date almost as soon as it’s sent. Plus, email often requires the consumer to take action forcing them to exit the email or opening a browser window, making the experience feel more fragmented or transactional. How can brands take better advantage of the time consumers spend in their inboxes to deliver more personalized experiences and drive higher engagement? The answer lies in creating emails that are both interactive, authentic and informative.  

To help brands stand out among the more than 290 billion emails that are sent every day and to further demonstrate its commitment to innovation, Adobe Campaign, part of Adobe Experience Cloud, is announcing compatibility with AMP for Email, supported by Gmail and other mail clients. Available to Adobe Campaign customers now, this innovative modern app functionality for email allows senders to include AMP components inside rich, engaging emails sent from Adobe Campaign Classic. Adobe Campaign is among the first group of email marketing solutions to be compatible with AMP for Email.

By leveraging AMP for Email within Adobe Campaign, marketers are able to deliver innovative email marketing campaigns by: 

  • Interacting with customers directly within email: Marketers will no longer have to rely solely on embedded hyperlinks. With AMP, customers will be able to interact with polls, make reservations, manage subscription preferences and more all directly within their email itself. Information captured in form fills syncs directly into Adobe Campaign, so marketers can build engaging email campaigns and gain actionable insights on their marketing efforts all from within the same application.   
  • Updating email content in real time: Content in static emails can quickly become out-of-date or irrelevant. Now information that is updated on a brand’s website can also be updated in real-time inside an email, even after it has already been sent. Thus, giving consumers the latest and most pertinent information and saving marketers the hassle of having to send out an additional message with updated information. For example, a retailer may have sent out a personalized email to a customer suggesting a new coat for the customer to purchase based on past behavior. At the time the email is sent, the coat may not be discounted, but by the time the customer opens the email, the coat is discounted 15%. The new price will be automatically updated within the email, providing the most accurate pricing to inform their purchase decision.  
  • Building dynamic customer experiences quickly and at scale: By leveraging AMP modules within Adobe Campaign, marketers can quickly and easily build interactive, personalized email experiences for customers regardless of the email client. AMP for email is currently supported by Gmail, Outlook and others.  

For more information on Adobe Campaign, click here.