Introduction
Welcome to my blog Freeplay!
Today the topic is How to build an app? Tutorial!
Hope this post might be useful to you and please stay tuned to our blog for further updates. Remember the end contains surprises!
In this article, I will guide you to build a PWA (Progressive Web app) for your website in an easy way.
So, before you start the process to set up PWA For your website, you must know what is PWA and why it is important for your website.
What is PWA (Progressive Web App)
Progressive web apps are a new way to create native-like experiences on the web. They combine the best of both worlds, providing users with the best of a website and an app.
A Progressive Web App is a webview app that can be installed on your phone or tablet like an app, but it's built with web technologies. This means you can add features like push notifications and offline support without having to build a separate native app.
Why is PWA Important?
A Progressive Web App is a website that behaves like an app on the user’s device. It loads quickly, is responsive to different devices, and can be accessed at any time without the need to download anything.
A Progressive Web App offers a better experience than a traditional website for both users and developers. It has features that are usually found in native apps such as push notifications, offline support, and home screen icons. This means that it will load faster, look better on all types of screens, have more functionality than a regular website, and will be available even when the device is offline.
How to build a PWA for Blogger
In order to build a Progressive Web App, you will need to add some features to your website. These features include service workers, which allow your site to work offline, and push notifications for when users return to your site. You can also install an Add-to-Home screen prompt on your website that prompts users to add your site or app to their home screen on their mobile device or desktop computer.
This tutorial may be a bit difficult to understand, but if you follow all the steps correctly, you will surely be able to build a PWA for your Blogger Website.
Full process
manifest.json
browserconfig.xml
icon-blogname i.e icon-fineshop
and upload your icons. Prepare 5 screenshots of your app and name them as:scr1.png
scr2.png
scr3.png
scr4.png
scr5.png
for example:
main-fineshop
manifest-fineshop
serviceworker-fineshop
offline-fineshop
10) Go to Workers section and click on Manage Workers. Click create a service and make these four services. Remember the names of those services are given at Step 12. Rename the
fineshop
to your blogname
.Quick edit
and replace the existing code with fhe given code.Main worker
addEventListener("fetch", event => { event.respondWith(handleRequest(event)) }) //const BUCKET_NAME = "main" const BUCKET_URL = `https://cdn.statically.io/gh/kumardeo080/icon-fineshop` async function serveAsset(event) { const url = new URL(event.request.url) const cache = caches.default let response = await cache.match(event.request) if (!response) { response = await fetch(`${BUCKET_URL}${url.pathname}`) const headers = { "cache-control": "public, max-age=14400" } response = new Response(response.body, { ...response, headers }) event.waitUntil(cache.put(event.request, response.clone())) } return response } async function handleRequest(event) { if (event.request.method === "GET") { let response = await serveAsset(event) if (response.status > 399) { response = new Response(response.statusText, { status: response.status }) } return response } else { return new Response("Method not allowed", { status: 405 }) } }
Manifest.json
addEventListener("fetch", event => { const data = { name: "Fineshop Design", short_name: "Fineshop Design", description: "Install Now Fineshop Design - Let's fuel creativity", display: "standalone", prefer_related_applications: false, start_url: "\/?utm_source=homescreen", scope: "\/", background_color: "#2196f3", theme_color: "#2196f3", icons: [ { src: "\/main\/android-icon-512x512.png", sizes: "512x512", type: "image\/png" }, { src: "\/main\/android-icon-192x192.png", sizes: "192x192", type: "image\/png" }, { src: "\/main\/apple-icon-144x144.png", sizes: "144x144", type: "image\/png" }, { src: "\/main\/android-icon-96x96.png", sizes: "96x96", type: "image\/png" }, { src: "\/main\/android-icon-72x72.png", sizes: "72x72", type: "image\/png" }, { src: "\/main\/android-icon-48x48.png", sizes: "48x48", type: "image\/png" }, { src: "\/main\/android-icon-36x36.png", sizes: "36x36", type: "image\/png" } ], shortcuts: [ { name: "Fineshop Design", short_name: "Fineshop Design", description: "The Best Website where you can find Blogger Widgets, Tech News, Tech Reviews, Coding related Tutorials and many more.", url: "\/?utm_source=homescreen", icons: [ { src: "\/main\/android-icon-192x192.png", sizes: "192x192" } ] }, { name: "Fineshop Design - Blog", short_name: "Fineshop Design - Blog", description: "Explore Fineshop Design Blog.", url: "\/search?utm_source=homescreen", icons: [ { src: "\/main\/android-icon-192x192.png", sizes: "192x192" } ] }, { name: "Blogger Widgets", short_name: "Blogger Widgets", description: "Useful Widgets for your Blog.", url: "\/search\/label\/Widgets?utm_source=homescreen", icons: [ { src: "\/main\/android-icon-192x192.png", sizes: "192x192" } ] } ], screenshots: [ { src: "\/main\/scr1.png", type: "image\/png", sizes: "540x720" }, { src: "\/main\/scr2.png", type: "image\/png", sizes: "540x720" }, { src: "\/main\/scr3.png", type: "image\/png", sizes: "540x720" }, { src: "\/main\/scr4.png", type: "image\/png", sizes: "540x720" }, { src: "\/main\/scr5.png", type: "image\/png", sizes: "540x720" } ], serviceworker: { src: "\/sw.js" } } const json = JSON.stringify(data, null, 2) return event.respondWith( new Response(json, { headers: { "content-type": "application/json;charset=UTF-8" } }) ) })
Service Worker
const js = ` importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js'); if (workbox) { workbox.core.skipWaiting(); workbox.core.clientsClaim(); workbox.core.setCacheNameDetails({ prefix: 'thn-sw', suffix: 'v22', precache: 'install-time', runtime: 'run-time' }); const FALLBACK_HTML_URL = '/offline.html'; const version = workbox.core.cacheNames.suffix; workbox.precaching.precacheAndRoute([{url: FALLBACK_HTML_URL, revision: null},{url: '/manifest.json', revision: null},{url: '/main/favicon.ico', revision: null}]); workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly()); workbox.routing.registerRoute( new RegExp('.(?:css|js|png|gif|jpg|svg|ico)$'), new workbox.strategies.CacheFirst({ cacheName: 'images-js-css-' + version, plugins: [ new workbox.expiration.ExpirationPlugin({ maxAgeSeconds: 60 * 24 * 60 * 60, maxEntries:200, purgeOnQuotaError: true }) ], }),'GET' ); workbox.routing.setCatchHandler(({event}) => { switch (event.request.destination) { case 'document': return caches.match(FALLBACK_HTML_URL); break; default: return Response.error(); } }); self.addEventListener('activate', function(event) { event.waitUntil( caches .keys() .then(keys => keys.filter(key => !key.endsWith(version))) .then(keys => Promise.all(keys.map(key => caches.delete(key)))) ); }); } else { console.log('Oops! Workbox did not load'); } ` async function handleRequest(request) { return new Response(js, { headers: { "content-type": "application/javascript;charset=UTF-8", }, }) } addEventListener("fetch", event => { return event.respondWith(handleRequest(event.request)) })
Offline
const html = `<!DOCTYPE html> <html> <head> <!--[ Meta Tags ]--> <title>Oops, You're Offline!</title> <meta charset='UTF-8'/> <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0' name='viewport'/> <meta content='IE=edge' http-equiv='X-UA-Compatible'/> <!--[ Theme Color ]--> <meta content='#2196f3' name='theme-color'/> <meta content='#2196f3' name='msapplication-navbutton-color'/> <meta content='#2196f3' name='apple-mobile-web-app-status-bar-style'/> <meta content='true' name='apple-mobile-web-app-capable'/> <!--[ Favicon ]--> <link href='/main/apple-icon-120x120.png' rel='apple-touch-icon' sizes='120x120'/> <link href='/main/apple-icon-152x152.png' rel='apple-touch-icon' sizes='152x152'/> <link href='/main/favicon-32x32.png' rel='icon' sizes='32x32' type='image/png'/> <link href='/main/favicon-96x96.png' rel='icon' sizes='96x96' type='image/png'/> <link href='/main/favicon-16x16.png' rel='icon' sizes='16x16' type='image/png'/> <link href='/main/favicon.ico' rel='icon' type='image/x-icon'/> <link href='/main/favicon.ico' rel='shortcut icon' type='image/x-icon'/> <!--[ Stylesheet ]--> <style>/*<![CDATA[*/ /* Merriweather - Font */ @font-face{font-family: 'Merriweather'; font-style: italic; font-weight: 300; font-display: swap; src: local('Merriweather-LightItalic'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7lXff4jvw.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7lXcf8.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: italic; font-weight: 700; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7NWPf4jvw.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR71Wsf8.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: italic; font-weight: 900; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7NWPf4jvw.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7NWMf8.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: normal; font-weight: 300; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l521wRZWMf6.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l521wRpXA.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: normal; font-weight: 700; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52xwNZWMf6.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52xwNpXA.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: normal; font-weight: 900; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52_wFZWMf6.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52_wFpXA.woff) format('woff')} /* Content */ body{background:#f1f3f6;color:#1f1f1f;font-family:'Merriweather',serif;font-weight:400;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body:focus{outline:none !important} .mainCont{margin:0 auto;position:fixed;left:0;top:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;padding:15px} .noIntPop{position:relative;overflow:hidden;text-align:center;padding:15px;border-radius:30px;background:#f1f3f6;box-shadow:inset 0 0 15px rgba(55, 84, 170, 0), inset 0 0 20px rgba(255, 255, 255, 0), 7px 7px 15px rgba(55, 84, 170, 0.15), -7px -7px 20px white, inset 0px 0px 4px rgba(255, 255, 255, 0.2)} .circle.t{top:-150px;right:-150px} .circle.b{bottom:-150px;left:-150px} .noIntCont{position:relative;z-index:1} .noIntIcon{padding:30px} .noConHead{font-weight:700;font-size:1.3rem} .noConDesc{font-size:16px;line-height:1.4em;padding-top:20px;font-weight:400;opacity:.8} .cta,.relCont{display:flex;justify-content:center;align-items:center} .relCont{padding:30px} .cta{width:66px;height:66px;background:#f1f3f6;outline:none;border:none;border-radius:690px;box-shadow:inset 0 0 15px rgba(55, 84, 170, 0), inset 0 0 20px rgba(255, 255, 255, 0), 7px 7px 15px rgba(55, 84, 170, 0.15), -7px -7px 20px white, inset 0px 0px 4px rgba(255, 255, 255, 0.2);transition:box-shadow 399ms ease-in-out} .cta:hover{box-shadow:inset 7px 7px 15px rgba(55, 84, 170, 0.15), inset -7px -7px 20px white, 0px 0px 4px rgba(255, 255, 255, 0.2)} .icon{content:'';width:25px;height:25px;display:inline-block} .iconB{content:'';width:50px;height:50px;display:inline-block} .icon.reload{background:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239dabc0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='23 4 23 10 17 10'/><path d='M20.49 15a9 9 0 1 1-2.12-9.36L23 10'/></svg>") center / 25px no-repeat} .iconB.wifiOff{background:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231f1f1f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><line x1='1' y1='1' x2='23' y2='23'/><path d='M16.72 11.06A10.94 10.94 0 0 1 19 12.55'/><path d='M5 12.55a10.94 10.94 0 0 1 5.17-2.39'/><path d='M10.71 5.05A16 16 0 0 1 22.58 9'/><path d='M1.42 9a15.91 15.91 0 0 1 4.7-2.88'/><path d='M8.53 16.11a6 6 0 0 1 6.95 0'/><line x1='12' y1='20' x2='12.01' y2='20'/></svg>") center / 50px no-repeat} .circle{position:absolute;z-index:1;width:280px;height:280px;border-radius:50%;background-color:#f1f3f6;box-shadow:inset 8px 8px 12px #d1d9e6, inset -8px -8px 12px #f9f9f9} /*]]>*/</style> </head> <body> <div class='mainCont notranslate'> <div class='noIntPop'> <div class='circle t'></div> <div class='circle b'></div> <div class='noIntCont'> <div class='noIntIcon'> <i class='iconB wifiOff'></i> </div> <div class='noConHead'>Oops, You're Offline!</div> <div class='noConDesc'>It looks like your network connection isn't working right now.</div> <div class='relCont'> <button class='cta' onclick='window.location.reload()'> <i class='icon reload'></i> </button> </div> </div> </div> </div> </body> </html>` async function handleRequest(request) { return new Response(html, { headers: { "content-type": "text/html;charset=UTF-8", }, }) } addEventListener("fetch", event => { return event.respondWith(handleRequest(event.request)) })
7) Rename each workers file as:
1) main-blogname i.e main-fineshop
3) serviceworker-blogname i.e serviceworker-fineshop
4) offline-blogname i.e offline-fineshop
Route | Service |
---|---|
www.fineshopdesign.com/main/* | main-fineshop |
www.fineshopdesign.com/manifest.json | manifest-fineshop |
www.fineshopdesign.com/sw.js | serviceworker-fineshop |
www.fineshopdesign.com/offline.html | offline-fineshop |
Set all environment to production.
Blogger Dashboard
<link href='/main/apple-icon-57x57.png' rel='apple-touch-icon' sizes='57x57'/> <link href='/main/apple-icon-60x60.png' rel='apple-touch-icon' sizes='60x60'/> <link href='/main/apple-icon-72x72.png' rel='apple-touch-icon' sizes='72x72'/> <link href='/main/apple-icon-76x76.png' rel='apple-touch-icon' sizes='76x76'/> <link href='/main/apple-icon-114x114.png' rel='apple-touch-icon' sizes='114x114'/> <link href='/main/apple-icon-120x120.png' rel='apple-touch-icon' sizes='120x120'/> <link href='/main/apple-icon-114x114.png' rel='apple-touch-icon' sizes='144x144'/> <link href='/main/apple-icon-152x152.png' rel='apple-touch-icon' sizes='152x152'/> <link href='/main/apple-icon-180x180.png' rel='apple-touch-icon' sizes='180x180'/> <link href='/main/android-icon-192x192.png' rel='icon' sizes='192x192' type='image/png'/> <link href='/main/favicon-32x32.png' rel='icon' sizes='32x32' type='image/png'/> <link href='/main/favicon-96x96.png' rel='icon' sizes='96x96' type='image/png'/> <link href='/main/favicon-16x16.png' rel='icon' sizes='16x16' type='image/png'/> <link href='/main/favicon.ico' rel='icon' type='image/x-icon'/> <meta content='#2196f3' name='msapplication-TileColor'/> <meta content='/main/ms-icon-144x144.png' name='msapplication-TileImage'/> <meta content='#2196f3' name='theme-color'/> <link href='/manifest.json' rel='manifest'/>
5) Add the following Javascript code above to </body>
<script>/*<![CDATA[*/ /* Service Worker */ if('serviceWorker' in navigator){window.addEventListener('load',()=>{navigator.serviceWorker.register('/sw.js').then(registration=>{console.log('ServiceWorker registeration successful')}).catch(registrationError=>{console.log('ServiceWorker registration failed: ', registrationError)})})}; /*]]>*/</script>
Conclusion
I expressed my views on the topic 'How to build an app? Tutorial'. Hope you are furnished my opinion. The post mustn't be copied without prior permission by emailing or telegram.Source:
https://www.freeplayus.in/2022/03/how-to-build-pwa-tutorial.html