Putting the AMP in Progressive Web AMPs: Meet the ShadowReader

We’ve previously written plenty about combining AMP & PWA, short for Progressive Web Apps. While the idea of preloading your PWA while the reader is reading your AMP page is fairly straightforward, the other combination pattern, where AMP is used as data-source to power your PWA, is less understood.

In my recent Google I/O talk, I claimed that you could get an AMP page to render within your PWA within a few minutes of writing code, and while that might be true, it doesn’t reflect all the work to be done in a production app. It was time to eat our own dogfood and build a production-ready PWAMP from scratch. Meet the Shadow Reader:


Contrary to our simpler previously released
React-based sample app, The ShadowReader demo app is is so-called ‘vanilla JS’ (with the exception of AMP, of course) – built from scratch to demonstrate all steps required to create the experience – and uses real-world feeds and AMP pages from The Guardian. You can experience it yourself on your phone (or via emulation) at https://amp.cards.

So what’s special about this app? For once, it demonstrates how quickly you can spin up a so-called “app shell” if you already have a corpus of AMP pages. Instead of a giant app that includes all templating logic to display articles, this app simply reads the Guardian’s RSS feeds, then delegates to AMP for rendering an existing AMP page inline when you click a card. This makes the engineering effort and app itself incredibly lightweight. More highlights:

  • Pulling in real-world data means solving real-world challenges
  • Weighs less than 10kb (~200kb if you include Guardian web fonts and AMP)
  • Smooth card transitions and skeleton UI’s to further accelerate perceived performance
  • Supports full URL-based navigation, sharing

If you’re a developer, dive through the source code and head over to my own blog to learn exactly how I’ve built each feature and element of the app, including the FLIP-based animations and the article views that seamlessly reconnect with lazy-loaded cards.

The Shadow Reader is half inspiration, half tutorial. Use it to evaluate whether the PWAMP route makes sense for your use-case, and don’t hesitate to reach out if you need help getting started. Now PWAMP all the things!

Paul Bakaus
AMP Developer Advocate, Google

Putting the AMP in Progressive Web AMPs: Meet the ShadowReader

AMP Roadmap update for end of Q2

We’ve updated the AMP Roadmap to reflect progress on existing priorities as well as several new projects. You can see the highlights below:


amp-bind, a flexible event binding system supporting more interactivity in AMP is now fully available in production. To find out more about the range of capabilities this feature brings to AMP, read our blog post. Recently we’ve also launched support for validating form inputs via AJAX (experimental but launching soon – example) and the building blocks to compose search-autosuggest using amp-bind.

We are also working on a set of features geared toward engaging experiences in AMP. Specifically, we’re planning to improve amp-image-lightbox this quarter, so developers can easily implement an immersive lightbox experience synced with amp-carousel. Scroll-bound animations are also slated to launch in the next couple months. Once that’s in place, we’ll re-purpose the general solution for parallax scrolling and contextually-displayed headers. Video will also get a new scroll-bound feature: the ability to minimize to the corner of the viewport after the inline video is scrolled away. This will enable users to seamlessly engage with other content on the page at the same time as a featured video.

In addition, we will soon make available new templates for AMP Start to help developers in more verticals make great-looking AMP pages. We’re also making it easier to configure AMP Start pages without having to edit code directly by developing an AMP Start template configurator.

Finally, we’ve started work on some longer-term features to support even more interactivity.

  • E-commerce websites in particular will benefit from dedicated client-side sorting & filtering components, as well as a date picker.
  • Those of you building responsive pages will benefit from a revamped sidebar component that has the ability to change display format based on the width of the viewport. For example, users can have a toggle-able sidebar on mobile that changes into a fixed-position header on desktop.
  • We’re expanding the capabilities of embedded content in AMP by supporting messaging between amp-iframe and other elements in the parent document.


As Q2 ended, we have begun to focus on supporting video analytics natively in amp-analytics, starting with amp-video. Available experimentally now and coming to production next week, publishers will be able to capture video-specific data that’s associated with video events like play and pause. The spec is available at the link above, so please give us any feedback on how the proposal matches up with your needs.

On other fronts, we are wrapping up work from the previous quarter to allow AMP extensions to collect data using amp-analytics, we plan to start work to support filters soon, and we expect to have various projects that add further ways to customize amp-analytics, like the reportWhen feature listed in the roadmap.


We’ve been working on helping publishers enhance ad request information for better targeting and therefore better monetization using a new feature called Real Time Config (RTC). RTC helps publishers earn more from their AMP inventory by enhancing the ad request with things like cookie-based targeting information or more broadly any audience related information in a safe and performant manner without negative consequences to the user experience. We want to ensure all targeting based use cases can be implemented using RTC. We look forward to your input on the Github Issue.

We are also addressing a long standing ask to enable sponsorship campaigns where advertisers require competitive exclusions or roadblocks in AMP pages. We’ve begun work on the ability to correlate all ad requests on an AMP page to achieve this functionality and will soon open it up for testing in experimental. Please let us know on Github if you’d like to test drive this feature.

As a reminder, we have a number of innovative AMP Ads (e.g. Lightbox ads created in AMP format) available on AMP By Example to modify and use for your own campaigns for free. With the launch of amp-animation, scroll bound animation based ads are also easy to incorporate in your direct sold campaigns.

* * *

Thanks to 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 Vamsee Jasti, Product Manager, AMP Project

AMP Roadmap update for end of Q2

amp-bind brings flexible interactivity to AMP pages

We invited developers to try out amp-bind in April to experiment with greater AMP page interactivity. Today we’d like to highlight that amp-bind is generally available and take a deeper dive into the feature, in order to give you a sense of just how much this expands AMP support—especially for e-commerce.

What is amp-bind?

We introduced amp-bind in an April blog post by saying:

amp-bind fundamentally changes the model for interactivity in AMP, while retaining AMP’s essential performance and UX assurances. amp-bind works more like a coding layer on top of AMP—going beyond the AMP Project’s historical approach of limiting interactivity to scoped, use-case-driven components like amp-carousel and amp-accordion. amp-bind links user actions with triggers for different document states, giving developers much more freedom in the types of interactions they can define.

While this definition is technically accurate, it’s also pretty abstract. The feature is so flexible that a broad description doesn’t really reveal what it can actually do.

What can amp-bind do?

One good way to start is to take a look at some of the basic behaviors for the feature. After that, you can try it out yourself by tweaking some of the code in the AMP by Example playground.

Building on what you’ve learned after mastering the basics, the examples below show you some of what’s possible when you combine amp-bind with other AMP HTML features.

  • Product color and size selection (detailed example below)
  • Server-side filter & sort (detailed example below)
  • Search results without page reload (detailed example below)
  • Search auto-suggest (detailed example below)
  • Carousel slide indicators (detailed example below)
  • Trigger navigation from “select” input
  • Smart buttons that update the state of the entire page state based on “like”, “thumbs up”, “add to cart”, etc. Could reveal a carousel of personalized recommendations based on this action, increment number of items in cart or “like” count.
  • Toggle between different views (list v. grid) of an array of items.
  • Toggle overlaying UI panels to customize product options before purchase
  • Hide/show tooltips
  • Use custom sliders to filter amp-list data
  • Change currency (e.g. from US dollars to euros) w/out updating the entire page
  • And more!

Product color and size selection


This example incorporates a number of features that are commonly found on product detail pages, though these features could also be separated and used individually if you don’t need the entire interaction. Here, amp-bind coordinates events and actions between amp-form, amp-selector, amp-carousel, and some basic CSS.

  1. User makes a selection in amp-form (with inputs using amp-selector for easy customization and clear semantics)
  2. There’s an event associated with each of these selections
  3. This event is coordinated through amp-bind to do a few things:
    1. trigger CSS display of one of three different amp-carousels (one for each color of apple)
    2. trigger “disabled” attributes (and therefore style) on form inputs where a particular size isn’t available for a particular color apple
    3. trigger updates to the price, based on the color of the apple

Because the page uses amp-bind, the user has visual confirmation of their selections, so they have the best possible understanding of their purchase before submitting the form.

Server-side filter & sort


Sorting & filtering with server-side data is now possible through amp-list[src] binding. It uses amp-bind to coordinate events and actions between the “select” input and amp-list. Let’s take a look step by step:

  1. User selects a sorting or filtering rule (let’s say “low to high”)
  2. There’s an event associated with changing the “select” input state
  3. This event is coordinated through amp-bind to trigger an update to an amp-list’s src attribute, appending a query param matching the sorting rule (?sort=price-ascending), which sends a call to the server
  4. The server responds with a list of results according to the sorting rule, which are rendered by amp-list according to its defined template

Because bind events can be triggered by an array of inputs, you can use this basic pattern for many other features, like adding additional results via a “show more” button, or paginating list results, so users can explore additional items in a list without re-loading the parent page. Developers You could even implement an experience where users refresh a list of personalized recommendations.

Best practice: statically display results on first loading the page, using div[placeholder], so there is no delay before the results are displayed to the user. Then, when the user interacts with the sorting & filtering mechanism, you can use amp-bind to issue a call through amp-list to an updated URL defined in the “src” attribute to display the results.

Search results without page reload


By fetching and displaying search results inline without a full page reload, users save bandwidth and can have a more seamless experience by retaining the context of the current page. The implementation approach is another application of binding to amp-list, this time using amp-form as well.

  1. User searches for “pear” through amp-form
  2. The event triggered by this search is coordinated through amp-bind to trigger an update to amp-list’s src attribute, appending a query param matching the search query (?searchProduct=pear), which sends a call to the server
  3. The server responds with a list of results according to the search query, which are rendered by amp-list according to its defined template

Search auto-suggest


This one (code here) adds a little bit more complexity to the amp-list[src] binding. It uses amp-bind to coordinate events and actions between amp-form and amp-list.

  1. User starts typing in the search box
  2. There’s an event associated with text input into form fields (debounced, to prevent these events from getting triggered with every button press)
  3. This event is coordinated through amp-bind to do two things:
    1. trigger visibility on a hidden div containing amp-list
    2. trigger an update to that amp-list’s src attribute, which sends a call to the server containing the partial query that the user has typed into the form
  4. The server responds with a list of potential results, based on this query, which amp-list renders through its template — and the user sees these options as auto-suggestions
  5. The amp-list template coordinates tapping on any one of these suggestions to update the form field, completing the interaction

Note: remember to turn off the browser’s automatic auto-suggest if you’re building your own, to avoid overlaying two different UIs for this function at the same time

Take a look at the example on GitHub to dive more into how this works. You can just copy-and-paste the example into your own page, and customize the template and your back end to serve just about anything: on one end of simplicity you could have more granular suggestions for words that the user could search for, and on the other you could display detail-rich cards for product results with prices, pictures, and ratings.

Carousel slide indicators


Here amp-bind is simply used to coordinate the index of amp-carousel with CSS styles on a simple page indicator (those four dots in the lower-left of the carousel).

  1. User swipes the slide in the carousel
  2. There’s an event associated with the change of the visible slide
  3. This event is coordinated through amp-bind to trigger a change in CSS styles for the pagination dots

This capability means that developers can configure a wide range of affordances to indicate that the carousel is swipeable, and don’t need to rely on the amp-carousel default arrows.

What’s next?

amp-bind is stable now, but it’s still actively getting more features. Based on feedback we’ve gotten from the community, we’re adding capabilities that make the component even more powerful—without sacrificing AMP’s essential performance and UX guarantees.

Among other things, the roadmap includes: updating URL query parameters and corresponding history state from bindings, to complete the sorting/filtering use-case; enabling messaging between iframes and their parent document, to enable rich interactions that cross the boundary between what can be inlined & embedded in AMP; and updated bindings to coordinate page state with forms validated through server calls.

Go forth! Explore! (and share what you find)

In the end, developers out there will probably discover more new capabilities than what we’ve identified here on the AMP team. So go forth! Explore! Experiment with amp-bind and let us know what you find—we’d love to see what you’ve built, and share with the broader AMP community.

As always, we want your feedback for amp-bind, and for any other feature you need support for in AMP. We’re looking forward to hearing from you!

Posted by Eric Lindley, Product Manager, AMP Project

amp-bind brings flexible interactivity to AMP pages