/amp-pwa-next

📽️⚡A simple movie list app featuring amp pages embedded in pwa and nice page transitions, deployed with nextjs

Primary LanguageTypeScriptMIT LicenseMIT

amp pwa next

homepage screenshot

type definitions code style GitHub Workflow Status

A simple movie list app featuring amp pages embedded in pwa and nice page transitions, deployed with nextjs

Featuring:

Table of Contents

Install

yarn install

Usage

yarn dev

Which will run next in dev mode

You might want to have the TMDB_API_KEY available as env var

Background

Motivation

The standard approach to amp is to duplicate every pages: one regular react app, and one amp on a different url.

nextjs offer this feature, with hybrid amp pages. serving amp on xx?amp=1 url

  • For one, this requires to painfully maintain react component to mimic amp ones. It restrain developers to use the most advanced cool amp component, such as amp-story.

    Using "Shadow AMP" allows us to focus on amp components.

  • Secondly, having two url for the same page (amp and non-amp) is confusing for the user.

    Placing the responsibility to redirect on the service worker allows to have one single url (as seen by the browser ) serving both amp at first, and pwa-shell once the app is installed.

Pros - Cons

TL;DR

Pros

  • no need to maintain both amp and non amp version of components
  • unique url for amp and non amp version of one page

Cons

  • sending full html pages as data (could impact network perf)

State of the Art

Features

Here is every features of the app broke down into steps.

Simple Nextjs app

codediffdemo

We start with the simplest nextjs config. With just one static page /about

Dynamic pages

codedemo

Let's add the dynamic pages, build from the tmdb api (ref).

Caching

The movie page will likely never change. We set a long term caching policy to avoid from re-building it (ref).

The root page is a list of popular movies and will change. We set a life time of one day (ref).

amp-list

We use amp-list to async fetch the latest popular movie on the movie page (ref).

On the root page, since the lists are above the fold, this technique is not recommended.

Cache control with Service worker

codediffdemo

We add a service worker to handle the content caching.

  • All the assets are pre-cached upon installation.

  • The content ( amp pages, json api results ) are cached at runtime.

We use the workbox webpack plugin (ref), + some tweaking to make it works with nextjs (ref).

PWA shell

codediffdemo

shadow amp

The amp page are embedded into a react component using amp.attachShadowDoc (ref).

redirecting

When the service worker is ready, whenever the user navigate to an amp page, the pwa shell get served instead (ref).

It then reads the actual url and initiate the loading of the amp doc (ref).

routing

In order to navigate from an amp page to another, the nextjs router is bypassed. The pwa shell page have it's own router (ref). Which prevent from re-mounting the page unnecessarily.

Favorite list

codediffdemo

We decide to have a page with user content.

This page synchronize data from the user localstorage, it is not an amp page.

amp-script

We leverage amp-script to add a small widget on every movie to allows user to add / remove the movie to their favorite list (ref).

amp-script allow us to

  • declare a click handler to update the localstorage value, and change the button label accordingly
  • read the localstorage value at mount, and change the button label accordingly

Page transition

codediffdemo

We add page transition. When clicking a movie on the homepage, it animate the movie poster.

The flow is:

  • intercept click event on the link (ref)
  • animate a pending stance for instant feedback
  • load and mount the next page (ref)
  • animate to the next position of the poster (ref)

License

MIT