Here’s one of the best essays I’ve ever read about why progressive web apps are important, how they work, and what impact they have on a business:
PWAs are powerful, effective, fast and app-like.
It’s hard to imagine a mobile web property that could not be significantly improved via PWA implementation. They can also potentially eliminate the need for many “vanity” native apps that exist today.
My only small disagreement with this piece is their use of the term “mobile web.” I know it’s a tiny thing to get persnickety over but my hot take after reading it is this: it’s important to remember that progressive web apps are for everyone, desktop and mobile users alike. I think it’s important to reiterate that there is no mobile web. And that our goal is to be better than native.
I’ve been reading Jason Grigsby’s new book on progressive web apps this past week and it’s exciting. Jason explains what PWAs are and how they work while while doing a bang-up job covering the business case for using them them, too. But perhaps you might be thinking that a PWA isn’t necessary for the project you’re working on right now. Well, Jason argues that progressive web apps are for everybody:
Should your website be a progressive web app? The answer is almost certainly yes. Even if you don’t think of your website as an “app,” the core features of progressive web apps can benefit any website. Who wouldn’t profit from a fast, secure, and reliable website?
One of the challenges I’ve experienced when thinking about how to apply a progressive web app to a project I’m working on is figuring out what content to cache. Should the homepage be cached? Do we make a custom offline page? What is useful information to provide a user in that context?
Jason goes there, too, and even describes how he tackles that for his own projects:
For cloudfour.com, we chose to only cache recently viewed pages because the main reason people come to our site is to read the articles. If we tried to anticipate which articles someone would want offline access to, we’d likely guess incorrectly. If we precached top-level pages, we might force people on a metered network connection to download content they would never look at…
That makes a ton of sense to me and I realize that the offline cache should probably be different depending on the situation and the website. For example, maybe a design agency website could replace the big flashy homepage with an offline page that only shows the phone number of the agency instead. Or perhaps a restaurant website could cache the food menu and make that experience offline, but remove all the images to make sure it’s not too impactful for folks on those metered networks.
Anyway, I think that Jason’s book is wonderful as it reveals to us all this complexity and a whole new set of opportunities to improve the design and experience of our websites, which, by the way, is something we should strive for in this new and exciting age of web app development.
PWA (Progressive Web Apps) have been with us for some time now. Yet, each time I try explaining it to clients, the same question pops up: “Will my users be able to install the app using app stores?” The answer has traditionally been no, but this changed with Chrome 72 which shipped a new feature called TWA (Trusted Web Activities).
Trusted Web Activities are a new way to integrate your web-app content such as your PWA with yourAndroid app using a protocol based on Custom Tabs.
In this article, I will use Netguru’s existing PWA (Wordguru) and explain step-by-step what needs to be done to make the application available and ready to be installed straight from the Google Play app store.
Some of the things we cover here may sound silly to any Android Developers out there, but this article is written from the perspective of a front-end developer, particularly one who has never used Android Studio or created an Android Application. Also, please do note that a lot of what we’re covering here is still extremely experimental since it’s limited to Chrome 72.
Step 1: Set up a Trusted Web Activity
Setting up a TWA doesn’t require you to write any Java code, but you will need to have Android Studio. If you’ve developed iOS or Mac software before, this is a lot like Xcode in that it provides a nice development environment designed to streamline Android development. So, grab that and meet me back here.
Create a new TWA project in Android Studio
Did you get Android Studio? Well, I can’t actually hear or see you, so I’ll assume you did. Go ahead and crack it open, then click on “Start a new Android Studio project.” From there, let’s choose the “Add No Activity” option, which allows us to configure the project.
The configuration is fairly straightforward, but it’s always good to know what is what:
Name The name of the application (but I bet you knew that).
Package name: An identifier for Android applications on the Play Store. It must be unique, so I suggest using the URL of the PWA in reverse order (e.g. com.netguru.wordguru).
Save location: Where the project will exist locally.
Language: This allows us to select a specific code language, but there’s no need for that since our app is already, you know, written. We can leave this at Java, which is the default selection.
Minimum API level: This is the version of the Android API we’re working with and is required by the support library (which we’ll cover next). Let’s use API 19.
There are few checkboxes below these options. Those are irrelevant for us here, so leave them all unchecked, then move on to Finish.
Add TWA Support Library
A support library is required for TWAs. The good news is that we only need to modify two files to fill that requirement and the both live in the same project directory: Gradle Scripts. Both are named build.gradle, but we can distinguish which is which by looking at the description in the parenthesis.
There’s a Git package manager called JitPack that’s made specifically for Android apps. It’s pretty robust, but the bottom line is that it makes publishing our web app a breeze. It is a paid service, but I’d say it’s worth the cost if this is your first time getting something into the Google Play store.
Editor Note: This isn’t a sponsored plug for JitPack. It’s worth calling out because this post is assuming little-to-no familiarity with Android Apps or submitting apps to Google Play and it has less friction for managing an Android App repo that connects directly to the store. That said, it’s totally not a requirement.
Once you’re in JitPack, let’s connect our project to it. Open up that build.gradle (Project: Wordguru) file we just looked at and tell it to look at JitPack for the app repository:
Every Android app has an Android App Manifest (AndroidManifest.xml) which provides essential details about the app, like the operating system it’s tied to, package information, device compatibility, and many other things that help Google Play display the app’s requirements.
The thing we’re really concerned with here is Activity (<activity>). This is what implements the user interface and is required for the “Activities” in “Trusted Web Activities.”
Funny enough, we selected the “Add No Activity” option when setting up our project in Android Studio and that’s because our manifest is empty and contains only the application tag.
Let’s start by opening up the manfifest file. We’ll replace the existing package name with our own application ID and the label with the value from the manifestPlaceholders variables we defined in the previous section.
Then, we’re going to actually add the TWA activity by adding an <activity> tag inside the <application> tag.
Now, we need to add a new meta-data tag to our application tag. This will inform the Android application that we want to establish the connection with the application specified in the manifestPlaceholders.
That’s it! we just established the application to website relationship. Now let’s jump into the conversion of website to application.
To establish the connection in the opposite direction, we need to create a .json file that will be available in the app’s /.well-known/assetlinks.json path. The file can be created using a generator that’s built into Android Studio. See, I told you Android Studio helps streamline Android development!
We need three values to generate the file:
Hosting site domain: This is our PWA URL (e.g. https://wordguru.netguru.com/).
App package name: This is our TWA package name (e.g. com.netguru.wordguru).
App package fingerprint (SHA256): This is a unique cryptographic hash that is generated based on Google Play Store keystore.
We already have first and second value. We can get the last one using Android Studio.
First we need to generate signed APK. In the Android Studio go to: Build → Generate Signed Bundle or APK → APK.
Next, use the existing keystore, if you already have one. If you need one, go to “Create new…” first.
Then let’s fill out the form. Be sure to remember the credentials as those are what the application will be signed with and they confirm your ownership of the application.
This will create a keystore file that is required to generate the app package fingerprint (SHA256). This file is extremely important as it is works as a proof that you are the owner of the application. If this file is lost, you will not be able to do any further updates to your application in the store.
Next up, let’s select type of bundle. In this case, we’re choosing “release” because it gives us a production bundle. We also need to check the signature versions.
This will generate our APK that will be used later to create a release in Google Play store. After creating our keystore, we can use it to generate required app package fingerprint (the SHA256).
Let’s head back to Android Studio, and go to Tools → App Links Assistant. This will open a sidebar that shows the steps that are required to create a relationship between the application and website. We want to go to Step 3, “Declare Website Association” and fill in required data: Site domain and Application ID. Then, select the keystore file generated in the previous step.
After filling the form press “Generate Digital Asset Links file” which will generate our assetlinks.json file. If we open that up, it should look something like this:
This is the file we need to make available in our app’s /.well-known/assetlinks.json path. I will not describe how to make it available on that path as it is too project-specific and outside the scope of this article.
We can test the relationship by clicking on the “Link and Verify” button. If all goes well, we get a confirmation with “Success!”
Yay! We’ve established a two-way relationship between our Android application and our PWA. It’s all downhill from here, so let’s drive it home.
Step 3: Get required assets
Google Play requires a few assets to make sure the app is presented nicely in the store. Specifically, here’s what we need:
App Icons: We need a variety of sizes, including 48×48, 72×72, 96×96, 144×144, 192×192… or we can use an adaptive icon.
High-res Icon: This is a 512×512 PNG image that is used throughout the store.
Feature Graphic: This is a 1024×500 JPG or 24-bit PNG (no alpha) banner that Google Play uses on the app details view.
Screenshots: Google Play will use these to show off different views of the app that users can check out prior to downloading it.
Let’s go to the last step and finally push our app to the store.
Using the APK that we generated earlier (which is located in the AndroidStudioProjects directory), we need to go to the Google Play console to publish our application. I will not describe the process of publishing an application in the store as the wizard makes it pretty straightforward and we are provided step-by-step guidance throughout the process.
It may take few hours for the application to be reviewed and approved, but when it is, it will finally appear in the store.
If you can’t find the APK, you can create a new one by going to Build → Generate signed bundle / APK → Build APK, passing our existing keystore file and filling the alias and password that we used when we generated the keystore. After the APK is generated, a notice should appear and you can get to the file by clicking on the “Locate” link.
Congrats, your app is in Google Play!
That’s it! We just pushed our PWA to the Google Play store. The process is not as intuitive as we would like it to be, but still, with a bit of effort it is definitely doable, and believe me, it gives that great filling at the end when you see your app displayed in the wild.
It is worth pointing out that this feature is still very much early phase and I would consider it experimental for some time. I would not recommend going with a production release of your application for now because this only works with Chrome 72 and above — any version before that will be able to install the app, but the app itself will crash instantly which is not the best user experience.
Also, the official release of custom-tabs-client does not support TWA yet. If you were wondering why we used raw GitHub link instead of the official library release, well, that’s why.