Progressive Web Apps By Example: Part 4
We turn our web application into a Progressive Web Application.

This article is part of the series that starts with Progressive Web Apps By Example: Part 1.
As the solution becomes more complex in this example, it is now available for download.
Side Bar into Deep Linking
One key feature of the web, deep linking, works as expected with Progressive Web Applications. As a matter of fact, it is one of the recommendations in Google Chrome Developers Tools PWA audit feature, i.e., Each page has a URL, .
We refactor our previous example using React Router. We first create a Home component:
and then use React Router to create three routes:
- /local-storage/: Loads the LocalStorage component
- /indexed-db/: Loads the IndexedDB component
- /: Loads the Home component; the Home component is the default for unmatched routes
In order to run this application, however, we need to change our hosting solution to one that supports single page applications with multiple URLs; GitHub Pages does not. If you did not know, in this configuration the web server will serve up index.html (available at the root) for any route that does not match an actual file.
One easy low-cost solution is to use Firebase Hosting. This example is available at:

Observations:
- Was not surprised to see that all of the routes worked when online; even unmatched routes
- I was surprised to see that, without any additional configuration, all the routes worked offline; even unmatched routes. This means that the PWA must itself understands that it is responsible to serve up all routes that do not match up to an actual file (in much the same way the web server does)
Making it a Progressive Web Application
In order to turn this example into an installable Progressive Web Application, we only need update a single configuration file; the web app manifest, i.e., public/manifest.json:
Observations:
- The description of these parameters can be found in the documentation The Web App Manifest
- In addition, we update / create the various images in the public folder: favicon.ico, icons-192.png, and icons-512.png
- For completeness, we update the title in public/index.html
- Google Chrome Developers Tools PWA audit tool will report no problems when inspecting it now
PWA on Android
When we open the PWA’s URL in Chrome, Chrome will automatically present the user an option to add the PWA to the home screen(s).

Once added the PWA appears along side the other applications on the home screen(s).

Observations:
- Additionally, the application will show up as an application in Apps and other contexts where application appear
- Starting the PWA will briefly loads a splash screen followed the PWA running full screen; the splash screen uses the colors in the web app manifest
- The PWA shares the same data storage as the web application running in Chrome, e.g., both the share the same Web Storage API and IndexedDB resources. This makes sense as these resources are shared across all applications running from the same origin (scheme, hostname, and port)
PWA on iOS
When we open the PWA’s URL in Safari, there is a relevant option, Add to Home Screen, in the share menu.

Once added the PWA appears along side the other applications on the home screen(s).

Observations:
- The PWA does not use any of the icons in the web app manifest, rather it shows a snapshot of the screen as the application’s icon
- Starting the PWA will briefly loads a white screen followed the PWA running full screen; does not use any of the colors in the web app manifest
- The PWA does not shares the same data storage as the web application running in Safari. In this sense, the iOS implementation makes the PWA more like an application, e.g., deleting the application deletes the data
- On iOS, the Add to Home Screen option is available for any web page; in this case, however, it does not run full screen
Danger, Danger
Was in the middle of writing the next article in this series; covering topics like the extra steps one must take to set the icon by adding iOS-specific values to public/index.html:
I then noticed a big problem.
I discovered that when running the installed PWA on iOS 12.2, I could not get it to update predictably.
One thing I considered is that maybe iOS was using the Firebase cache headers (1 hour) and thus preventing timely updates. So, I waited over an hour; still could not get updates to happen. For completeness, I updated the Firebase cache control headers to prevent caching and did some careful testing:
Here is what I found (tried multiple times to confirm):
- Update the application and deploy to Firebase
- Reload the URL in Chrome desktop (my development machine) and it reports that a new version is available; closing tab and re-opening loads the updated version (good)
- Open the installed PWA on Android and it reports a new version is available; closing the application and re-opening loads the updated version (good)
- Open the installed PWA on iOS and nothing; no reports of a new version, no updated version. Open and closing the PWA multiple times did not help (problem)
Through a lot of troubleshooting, I noticed some things:
- The web application running in iOS Safari works mostly as expected; reporting the new version and closing tab and re-opening loads the updated version (good). The one oddity is that closing and opening Safari while running the web application does not update it; one has to close and open a tab to update the application
- If I restart my iOS device, I do get the updated version (weird)
- Found some questions/answers on the Internet that hint at the need to restart the iOS device or wait for some undetermined time to get updates
Wrap Up
I was prepared to recommend using PWAs in 2019; even knowing that one would have to do some minor work-arounds on iOS.
But without a way to predictably and reasonably (forcing user to restart is not reasonable) update the PWA on iOS, I cannot make such a recommendation.
Dang it Apple!