In the previous post, we discussed the concept of PWA. Today we’re going to practice an example – TwentyEA Insight project, step by step. We’re using Laravel for this project but it’s the same as other PHP frameworks even other programming languages.
STEP 1: Generate icons, Manifest file in public/pwa/
We must have icons at 192×192 px and 512×512 px. The easiest way is using https://www.favicon-generator.org/ to generate icons. They also give us the HTML code to put in our layout.
STEP 2: Update Manifest file at public/pwa/icons/manifest.js
{
“name”: “TwentyEA Insight”,
“short_name”: “Insight”,
“lang”: “en-US”,
“start_url”: “/”,
“background_color”: “#2C3E50”,
“theme_color”: “#18BC9C”,
“display”: “fullscreen”,
“icons”: [
{
“src”: “\/pwa/icons/android-icon-36×36.png”,
“sizes”: “36×36”,
“type”: “image\/png”,
“density”: “0.75”
},
{
“src”: “\/pwa/icons/android-icon-48×48.png”,
“sizes”: “48×48”,
“type”: “image\/png”,
“density”: “1.0”
},
{
“src”: “\/pwa/icons/android-icon-72×72.png”,
“sizes”: “72×72”,
“type”: “image\/png”,
“density”: “1.5”
},
{
“src”: “\/pwa/icons/android-icon-96×96.png”,
“sizes”: “96×96”,
“type”: “image\/png”,
“density”: “2.0”
},
{
“src”: “\/pwa/icons/android-icon-144×144.png”,
“sizes”: “144×144”,
“type”: “image\/png”,
“density”: “3.0”
},
{
“src”: “\/pwa/icons/android-icon-192×192.png”,
“sizes”: “192×192”,
“type”: “image\/png”,
“density”: “4.0”
},
{
“src”: “\/pwa/icons/android-icon-192×192.png”,
“sizes”: “512×512”,
“type”: “image\/png”
}
]
}
Here some required fields for the manifest file.
- name – display before app be loaded
- short_name – display on the home screen
- display – should use fullscreen to look like native apps as the concept of PWA 🙂
- start_url
- icons – Must be at least 192x192px and 512x512px.
STEP 3: Created Js file for Service Worker
created sw.js at “public/sw.js”.
//This is the “Offline copy of pages” wervice worker
//Install stage sets up the index page (home page) in the cahche and opens a new cache
self.addEventListener(‘install’, function(event) {
var indexPage = new Request(‘index.html’);
event.waitUntil(
fetch(indexPage).then(function(response) {
return caches.open(‘pwabuilder-offline’).then(function(cache) {
console.log(‘[PWA Builder] Cached index page during Install’+ response.url);
return cache.put(indexPage, response);
});
}));
});
//If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener(‘fetch’, function(event) {
var updateCache = function(request){
return caches.open(‘pwabuilder-offline’).then(function (cache) {
if (event.request.cache === ‘only-if-cached’ && event.request.mode !== ‘same-origin’) {
return;
}
return fetch(request).then(function (response) {
console.log(‘[PWA Builder] add page to offline’+response.url)
return cache.put(request, response);
});
});
};
event.waitUntil(updateCache(event.request));
event.respondWith(
fetch(event.request).catch(function(error) {
console.log( ‘[PWA Builder] Network request Failed. Serving content from cache: ‘ + error );
//Check to see if you have it in the cache
//Return response
//If not in the cache, then return error page
return caches.open(‘pwabuilder-offline’).then(function (cache) {
return cache.match(event.request).then(function (matching) {
var report = !matching || matching.status == 404?Promise.reject(‘no-match’): matching;
return report
});
});
})
);
})
The power of PWA is right here. In this, we can cache anything to make our app be able to run offline. We can cache request, data, etc.
STEP4 : Put HTML code in <head> of tempate file
<link rel=”apple-touch-icon” sizes=”57×57″ href=”{{ url(‘/pwa/icons/apple-icon-57×57.png’) }}“>
<link rel=”apple-touch-icon” sizes=”60×60″ href=”{{ url(‘/pwa/icons/apple-icon-60×60.png’) }}“>
<link rel=”apple-touch-icon” sizes=”72×72″ href=”{{ url(‘/pwa/icons/apple-icon-72×72.png’) }}“>
<link rel=”apple-touch-icon” sizes=”76×76″ href=”{{ url(‘/pwa/icons/apple-icon-76×76.png’) }}“>
<link rel=”apple-touch-icon” sizes=”114×114″ href=”{{ url(‘/pwa/icons/apple-icon-114×114.png’) }}“>
<link rel=”apple-touch-icon” sizes=”120×120″ href=”{{ url(‘/pwa/icons/apple-icon-120×120.png’) }}“>
<link rel=”apple-touch-icon” sizes=”144×144″ href=”{{ url(‘/pwa/icons/apple-icon-144×144.png’) }}“>
<link rel=”apple-touch-icon” sizes=”152×152″ href=”{{ url(‘/pwa/icons/apple-icon-152×152.png’) }}“>
<link rel=”apple-touch-icon” sizes=”180×180″ href=”{{ url(‘/pwa/icons/apple-icon-180×180.png’) }}“>
<link rel=”icon” type=”image/png” sizes=”192×192″ href=”{{ url(‘/pwa/icons/android-icon-192×192.png’) }}“>
<link rel=”icon” type=”image/png” sizes=”32×32″ href=”{{ url(‘/pwa/icons/favicon-32×32.png’) }}“>
<link rel=”icon” type=”image/png” sizes=”96×96″ href=”{{ url(‘/pwa/icons/favicon-96×96.png’) }}“>
<link rel=”icon” type=”image/png” sizes=”16×16″ href=”{{ url(‘/pwa/icons/favicon-16×16.png’) }}“>
<link rel=”manifest” href=”/pwa/icons/manifest.json”>
<meta name=”msapplication-TileColor” content=”#ffffff”>
<meta name=”msapplication-TileImage” content=”{{ url(‘/pwa/icons/ms-icon-144×144.png’) }}“>
<meta name=”theme-color” content=”#ffffff”>
<!– Service worker registration –>
<script type=”text/javascript”>
if(‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘{{ url(‘/sw.js’) }}‘, {scope: ‘/’})
.then(function (registration) {
console.log(‘Service Worker Registered’);
});
navigator.serviceWorker.ready.then(function (registration) {
console.log(‘Service Worker Ready’);
});
}
</script>
{{– Preloader –}}
Now we are done with coding, let’s take a look at Chrome debug tool to make sure everything is ready.
STEP5: Audits, Manifest checking on PC
Hit “Run audits” button
Audits result
Manifest result
Sometimes you’ll get “No manifest detected”. Try clicking on “Run audits” again and fix the error on that.
Service worker result
STEP 5: Experience the result
On IOS
On Android
The required fields show PWA popup on Google Chrome on Android
Only on Android popup will be showing as a minibar. On IOS, you have to follow this “Share > Add To Homescreen” as mentioned in the previous post.
- The web app is not already installed
- Meet a user engagement heuristic (currently, the user has interacted with the domain for at least 30 seconds)
- Include a web app manifest that includes:
- short_name or name
- icons must be a 192px and a 512px sized icons
- start_url
- display must be one of fullscreen, standalone, or minimal-ui
- Served over HTTPS (required for service workers)
- Has registered a service worker with a fetch event handler
Hope you find this issue useful. Comment down below if you have any question or contact us via email for free consultation. Don’t forget to share & subscribe to our blog! See you in the next post!
Hung Pham