This article is the last part of the 3-part series on building a Progressive Web Web. If you landed here first and need to review the previous articles, here is Part 1 and Part 2.
To create an end to end mobile experience for your users, you need to make them feel like the app is native by providing some of the features that their usual native apps provide them already. Some of which include:
- Working offline
- Adding app icon to home screen
- Splash screens
- Standalone experience
You already took care of the first feature in the previous parts. The last three is simpler and fun to implement. All you just need is a manifest.json
file.
Manifest
The manifest file is a JSON file where you configure how your app appears to users by adding icons and splash screens. It also lets you define what URL the app is accessed with when launched from the app icon. Basically, all other PWA features that except offline capabilities are configured here.
At bare-bones, this is what a manifest.json
file looks like:
{
"short_name": "",
"name": "",
"icons": [
{
"src":"",
"sizes": "",
"type": ""
}
],
"start_url": "",
"background_color": "",
"theme_color": "",
"display": ""
}
Create a manifest.json
file at the root of your app and copy-paste the above into that file. For now, the values are left empty. Let's visit each of the properties and discuss what they do while providing their values.
Name and Short Name
The name
and short_name
properties define the application name. They are usually the brand name of the app or whatever is found in the title tag of your index.html
.
The name
property is used where the user needs to see the full brand and of course where there is enough room for it. Otherwise, in cases where there is no enough room for the name
property, the short_name
is used.
For our app, same value makes sense for both properties:
{
"short_name": "Git Trends",
"name": "Git Trends",
}
App Icons
The icons
property takes an array of icons. There is a reason for this. It allows the browser to choose which icon makes sense on particular display size and density. Most times, 192 x 192 fits most cases so you might just end up having one item in the array with that value.
"icons": [
{
"src":"images/gt-icon192x192.png",
"sizes": "192x192",
"type": "image/png"
}
]
- src: is the location of the image relative to where the manifest file is located.
- sizes: The size of the image. This value is what the browser looks at when deciding what icon to use for a display size and density.
- type: The image type.
These icons will be sized based on the devices they are loaded. Therefore, to be on a safer side, you could provide a range of icons, especially in production. Maybe:
"icons": [{
"src": "images/touch/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
}, {
"src": "images/touch/homescreen72.png",
"sizes": "72x72",
"type": "image/png"
}, {
"src": "images/touch/homescreen96.png",
"sizes": "96x96",
"type": "image/png"
}, {
"src": "images/touch/homescreen144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "images/touch/homescreen168.png",
"sizes": "168x168",
"type": "image/png"
}, {
"src": "images/touch/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}]
Colors
App manifest allows you to set two different colors -- background color as background_color
and theme color as theme_color
.
- The background color should match the background color of your app. This would enable smooth and seamless transitioning from the splash screen to the app. In our case, it's white. Unfortunately, white is quite could send a wrong signal to the user implying that the app is blank. Therefore we can stick with the same color as the theme color.
- The theme color is usually the color on the navigation bar. In our example, it's teal (
#009688
):
Update manifest.json
with the colors:
{
"background_color": "#009688",
"theme_color": "#009688"
}
Display
This determines whether the browser's surroundings will show or not. Removing the surrounding makes the app feel more like a native app. To remove, just add standalone
:
{
"display": "standalone"
}
Start URL
The start URL is the page that the user sees when the launch your app from the home screen. This is usually the home page of the app:
{
start_url: "/utm_source=homescreen"
}
For marketing purposes, you can also gather data about users launching the app as PWA using utm_source
.
Add Manifest File To Page
For the manifest file to be recognized by your file, you need to include it in your index.html
. But before you do so, it is recommended to use a validation tool to validate the manifest file.
Validate Manifest
- Go to https://manifest-validator.appspot.com/
- Copy the manifest into the text area and click validate
- You should see a message the following if the validation was successful:
Add Manifest to Page
Now that you have a valid manifest, you can add to the index.html
:
<link rel="manifest" href="/manifest.json">
Deploying to GH Pages
Though we can test these shiny features using the debug console, it's better to do a test on a real device. To do so, we just need to deploy and access the URL from a real mobile device.
GH pages is free, so we can just deploy there:
- Install the GitHub Pages SDK:
npm install gh-pages --save-dev
- Add the following line to your
package.json
scripts:
"deploy": "gh-pages -d ."
- Setup a GitHub repository and add it as origin:
git remote add origin <GITHHUB-URL>
npm run deploy
Mobile Testing
Visit the app on your Android mobile device, reload and notice how fast the reloads are. Next, go to Chrome menu and add to home screen:
You should see a confirmation image where you can even edit the app name we specified in the manifest file:
Click add and go to your home scree to see the launcher icon:
Launch the app from the icon to see the super sweet splash screen:
Conclusion
PWA is just so exciting. Congratulations for making it this far because you have just learned how to build progressive web apps. Next things you can dig deeper to get better are concepts like Push Notifications, Performance, etc. Follow common web practices, and you should be good to go. Keep in mind that except for localhost
your service worker can only work with HTTPS
. Thank you!