Creating a simple PWA

PWA (aka Progressive Web Apps) is a type of application software delivered through the web, built using common web technologies including HTML, CSS and JavaScript. It is intended to work on any platform that uses a standards-compliant browser.

PWA is something that once you learn, you should be able to implement to almost any of your projects because the code is same for each PWA, no matter what the application does. I’ll be able to give you a template that you can add to your website, and thus, create a PWA.

PWA allows you to “install” your websites to your computer and mobile devices, which can be then used even offline and works like a normal app.

A PWA contains 4 essential things:

  1. manifest.json: it is more like the config file of the PWA
  2. sw.js: PWAs use Service Workers to cache assets and make them progressive
  3. some JS code to register the service workers
  4. a file full of logos of your website each one of a different dimension for each device.

We’ll create a manifest.json first.

  1. Go to https://app-manifest.firebaseapp.com/ and fill in all the details of your app. Make sure to leave ‘Orientation’, ‘Start URL’ and ‘Application Scope’ as it is. As for the display mode, I recommend you choose ‘Standalone’ as that is what makes the PWA a PWA :wink: but you’re free to choose whatever you like. Fill in background color and theme color according to your wish. Click on “Copy” near the manifest.json preview.

  2. Create a new file named manifest.json and paste all the contents into that file.

  3. First things first, you should have a 512x512 sized logo for the PWA. Go to https://app-manifest.firebaseapp.com/ and then fill in all the details. Make sure to leave ‘Orientation’, ‘Start URL’ and ‘Application Scope’ as it is. As for the display mode, I recommend you choose ‘Standalone’ as that is what makes the PWA a PWA :wink: but you’re free to choose whatever you like. Then on the right side, upload the 512x512 icon and you’ll get to download a ZIP file which contains your logo with different dimensions along with the manifest.json file with all the values we entered. For your PWA, you need an icon, with a recommended size of 512x512 pixels. Then, you can use a module named pwa-asset-generator to generate assets for your PWA.

$ npm install --global pwa-asset-generator
pwa-asset-generator /path/to/icon/png/jpg ./pwaicons/ -m ./manifest.json -i path/to/index.html

All the icons and splash screens will be generated in the pwaicons/ folder.

It will also automatically update your index.html file with the necessary meta tags.

You can configure the CLI to modify the generated icons and related config, see https://github.com/onderceylan/pwa-asset-generator#usage

If you change the location of the logos, make sure to update their paths in manifest.json as well, because the manifest.json has each of the logos (of different sizes) with their urls.

  1. Now for some JS! Create a file named sw.js or anything that indicates that the file is a service worker.

Copy this code into your sw.js file:

const staticCacheName = 'name-of-pwa';
const assets = [
  './scripts.js',
  './style.css',
];

self.addEventListener('install', evt => {
  evt.waitUntil(
    caches.open(staticCacheName).then((cache) => {
      console.log('caching shell assets');
      cache.addAll(assets);
    })
  );
});

self.addEventListener('activate', evt => {
  evt.waitUntil(
    caches.keys().then(keys => {
      return Promise.all(keys
        .filter(key => key !== staticCacheName)
        .map(key => caches.delete(key))
      );
    })
  );
});

self.addEventListener('fetch', evt => {
  evt.respondWith(
    caches.match(evt.request).then(cacheRes => {
      return cacheRes || fetch(evt.request);
    })
  );
});

In line 2 of the code, you’ll see an array named assets. And I have included a few urls as an example. In that array, make sure to add all the assets your project uses, such as images, fonts, scripts and styles. What happens is, the service worker will cache all the urls and files listed in the array for a “Progressive Web App”. Also make sure to replace name-of-pwa on line 1 with the name of your pwa (or any name for identification of the cache).

  1. Now, we move towards the HTML file. In your main HTML file, before the closing <head> tags, add the following code:
<script>
if('serviceWorker' in navigator){
  navigator.serviceWorker.register('sw.js')
    .then(reg => console.log('service worker registered'))
    .catch(err => console.log('service worker not registered', err));
}
</script>

In line 2 of the above code, make sure to replace sw.js with the file path of the service worker file we created in the above step.

  1. Then in our HTML file, we also add a link to the manifest.json file. Add the following code before the closing <head> tags:
<link rel="manifest" href="/manifest.json">

Make sure the href points towards the location of the manifest.json file.

All the above files including the images of different sizes are static assets, so if you have a separate configuration for static assets (like the public folder for an Express/Node.js setup), make sure to add all the above files into the static directory and make sure the urls everywhere point correctly to the desired file.

To make sure your PWA works fine,

  1. You should see a log in your DevTools console saying “service worker registered”

  2. On Chrome, you should see an Install button on the right side of the address bar.

  3. It should work offline (after visiting the app once online)

  4. Audits for Progressive Web Apps on Lighthouse should give a good score and determine whether it’s a PWA based on certain aspects of PWAs, with which you can improve your PWA.

Some great PWAs to check out:

  • Hoppscotch
  • MarkMe!
  • Twitter - yes, Twitter is a really great PWA. There’s almost no difference in installing Twitter’s website as a PWA and installing the Twitter app from the Play Store or iOS Store.

~Bonus~:

You can upload your PWA to Google Play Store which can then be installed. (Instructions for that coming up soon!)

8 Likes

before the word gets around we can pretend we hacked school ipads and installed the twitter app on them
these are all quite great apps, hhopscotch’s ui looks a bit like discord on the side.
You know what should be a PWA if it isn’t already: Scratch! I actually forked scratch-3 in it’s early developement just to sort of turn it into a PWA

2 Likes

Actually Hoppscotch is Postwoman.io’s new name.

Postwoman (now Hoppscotch) is an online alternative to Postman

1 Like

There’d be a lot of assets to cache, including all the sprites and backdrops to create an effective PWA for Scratch.

Are you talking about scratch.mit.edu or what?

I often use that but did not notice the change.

1 Like

Yes, https://scratch.mit.edu

I see.

Is a favicon really necessary?

Yes, it’s required for a PWA. And one icon is not enough, you need to generate the icon for different sizes (for various devices). I know, this can be a bit time consuming and exhausting (especially on Glitch because you can’t simply just upload those icons to Assets :sweat_smile:).

2 Likes

I see. Thank you.

2 Likes

When I clicked the Generate .ZIP button, I got this error-

Go 1.9 is no longer available. Please refer to Feature deprecations  |  Google App Engine standard environment docs  |  Google Cloud for more information.

That is really weird, that was a really good tool, let me see if there are any alternatives to that generator, although it worked last week.

I have found a workaround, will be updating the main post soon.

@R4356th I have update the main post, it should work now.

2 Likes

I know something that does something similar but it doesn’t look as good

And what would that be?

I found this but it seems to be more icon oriented
https://www.favicon-generator.org/

That would be great as well, we can still use the Web App Manifest Generator that I originally posted to generate manifest files.

this is off topic but MarkMe! is not a very good PWA

(no offense, lol, I was just joking with @khalby786)

Great tutorial anyways!

Hey @khalby786,

Is there another working PWA making website? I don’t use Node for my website and I would like to make it a PWA.

make it yourself :wink:

Don’t think I would be asking if I could make one myself.

3 Likes

https://qr.ae/pN242J

Node isn’t necessary to create a PWA. However in this case, to generate the logos you could use node in a separate app, unless there is a better online tool to generate logos and splash screens dynamically of different sizes for your app.

For best possible experience, please use Node.

I couldn’t find one as good as https://app-manifest.firebaseapp.com/, will let you know if I find an online alternative, although the CLI generator is really good.

2 Likes

Your feedback on why MarkMe! is not a good PWA and steps I could do to improve the experience can be said here.

I did see the “I’m kidding” part, but MarkMe! is still lacking some of the PWA guidelines.

1 Like

ya and I’d don’t know how to make a pwa really, so you can throw as many insults as you wish at me about them!

Hey @code-alt, I was truly asking for your feedback on MarkMe!'s PWA functionality and it was no insult. I asked you to post in the other thread because it would be off topic if posted here.

1 Like

oh…

welp sorry bout that

1 Like

I think Discourse forums are PWAs, too.

1 Like

Yes, they are. However, I don’t see an Install option on Chrome for this forum.

3 Likes

there is a mobile view option

2 Likes

Yes, maybe Discourse has not been updated or something similar.

2 Likes

Discourse has every thing they need.

Discourse even works offline

1 Like

Help me set up PWA. I have an error showing in Lighthouse: This origin has one or more service workers, however the page (https://worldplay.tk /) is not in scope. Website — https://worldplay.tk. Project — Glitch :・゚✧ /#!/worldplay. How do I fix this error? What am I doing wrong?

How this PWA can be installed on IOS-Safari browser?

hi @Fatima_Aslam! you can install a PWA on iOS [1] by choosing the Add to Home Screen option in the Share menu on Safari.


  1. For iOS versions before 16.4, PWAs can only be installed in Safari. PWAs can be installed on iOS/iPadOS 16.4 or later from any supporting browser. ↩︎