Friday, April 17, 2020

Your First (rudimentary) PWA in Seven Steps


Introduction, audience, and scope

This is a very, very basic tutorial. I will refrain from even calling it ‘bare-bones’ because that skeleton would be missing the metacarpals and a femur, so to speak.

The goal, or use case, is simply to get the app to pass the PWA audit in Chrome and make the app downloadable to a user’s machine, should the user decide they are better off using an offline version of the application.

To begin with, you should already have written and fully debugged a dirt-simple, front-end only HTML/JavaScript app that does not require any external resources (it does not connect to an API for data, for example).

To see the example I used, go to here .

Besides some basic HTML and JavaScript, some introductory knowledge of service workers is a prerequisite for this tutorial. PWA is where you will really start of suffer from and then master service workers. If you are absolutely new to service workers, stop here and go do one or two tutorials that are focused just on service workers. Then come back.

Please note that I am using a Windows 10 machine and the Chrome browser for all of this. If you are following the steps of this tutorial and getting different results, first check to see if the issue may be that you are using a different setup.

Make your app visible to Chrome

I am using Chrome’s Audit feature to get started on the PWA version of the app (Audit comes with Chrome - just open Chrome and hit F12 to see the dev tools; Audits is one of the tabs across the top). In order for Audit to see your app, and then later for service workers to function properly, your app has to be in a HTTP/HTTPS document. You cannot just be running your app on local host. There’s probably half a dozen better ways to go about meeting this requirements, but what I did to accomplish this was just to host my app on GitHUB pages.

(For more of a nuts and bolts guide to actually setting up a GitHub Pages website manually without all the bells and whistles, go to my earlier post).

NOTE: If you opt for GitHub pages, always use full reference paths as opposed to partial paths. Absolutely make sure to name the main file “index.html” or GitHub Pages won’t work in your browser.

Audit your app and clean up failures

Once you have reached the point where you can view your app the in Chrome web browser as a HTTP/HTTPS doc, you are ready to run an audit in Chrome and figure out where to go from here.
Click F12 and that will open the Chrome dev tools. Up at the top where it says “Elements,” “Console,” “Sources,” etc,. click on the “Audit” tab. On the “Audit” tab, click the “Generate report” button.

There will probably be lotsa red telling you how miserably your site fails to meet basic industry standards.

At this point you could easily ignore the components of the Audit that do not have to do directly with PWA and just move on. But loose ends drive me batty so I cleaned them up. Just google each statement and patch up your HTML accordingly.

Add a manifest.json file

PWA requires a ‘manifest.json’ file in the root directory. You have to title the manifest ‘manifest.json’ and save it as a .json file.

The manifest you are starting out with in this tutorial is very minimal. Other more advanced tutorials will show you how to do more with the manifest and more with logos. For now we are just keeping things dirt-simple.

Your manifest should look like this (fill in what you want for ‘name,’ ‘short_name,’ and the colors):

  {
  "name": "<the name of your app>",
  "short_name": "<the name of your app>",",
  "icons": [
    {
      "src": “images/192_icon.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "images/512_icon.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "https://<username>.github.io/index.html",
  "display": "standalone",
  "background_color": "<the color you want>",
  "theme_color": "<the color you want>"
}

In a typical PWA, there are actually more than just the two icon/icon sizes used. But these two – 192 px and 512 px - are the bare minimum to get a PWA up and running, and this is a bare-minimum tutorial. In fact, I just went out and googled “free test icons,” one for 192 pix and one for 512 px. I copied and pasted them to good ol’ Paint, saved them as jpegs, then uploaded them to a ‘images’ folder in the root directory of the GitHub page. 

Create an offline version of the app

Just create a copy of the index.html file in the root directory. Title this new file ‘offlineApp.html.’
In a full PWA application, something that is beyond the scope of this tutorial, the offline version of the app is part of what allows PWA to turn your app into something that can seamlessly transition between an online and an off-line experience. It's a big deal. But given the very limited scope of this tutorial, just create and rename the copy of index.html for now. Consider it a stub where the future offline version of the app will go when you know more about PWA.

Create the Service Worker

Now, create the service-worker.js file in the root directory. Here is my code for my service-worker.js file:

  const myCache = 'static-cache';
  const pageToCache = [ '/offlineApp.html' ];

  self.addEventListener('install', function(event) {
    event.waitUntil(
      caches.open(myCache)
      .then(function(cache) {
        return cache.addAll(pageToCache);
      })
    );
  });

  self.addEventListener('fetch', function(event) {
    event.respondWith(
      caches.match(event.request)
      .then(function(response) {
        return response || fetchAndCache(event.request);
      })
    );
  });

  function fetchAndCache(url) {
    return fetch(url)
    .then(function(response) {
      // check for valid response
      if (!response.ok) {
        throw Error(response.statusText);
      }
     return caches.open(myCache)
      .then(function(cache) {
        cache.put(url, response.clone());
        return response;
      });
    })
    .catch(function(error) {
      console.log('Request failed:', error);
      // offline 404 page really needs  go here but I have not bothered yet
    });
  }

Reference service-worker.js and manifest.json in index.html

Our goal, again, is a very limited one. We just want to use PWA to let the user download the app from the page where the app is hosted.

Add the following to the header section of your HTML:

  <link rel=”manifest” href=”https://< username>.github.io/manifest.json” />

NOTE: Always use ‘https’ in your links and not ‘http,’ otherwise you will create what is known as a cross-origin error. This is because GitHub resources always use the secure ‘https’ protocol.

Go to your index.html page and add a <script></script> section. Add the following code:

  if ('serviceWorker' in navigator) {
   window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
     .then((reg) => {
      console.log('Service worker registered.', reg);
     });
    });
  }

Test

That’s pretty much it. If you run your app in your Chrome browser, check out the three vertical dots icon. There should now be an option to install a stand-alone version of your app. Congrats – you’ve got your first PWA up and running!

Troubleshooting

App not working on other browsers?

Not all browsers support the web app manifest the same way Chrome does. But you want your app to work on all browsers if possible. Try updating your meta-tags in index.html to help out other browsers. Add the following to the header section of your index.html file:
  <meta name = “apple-mobile-web-app-title” content=”myApp” >
  <meta name = “apple-mobile-web-app-status-bar-style” content=”blue” >
  <meta name = “apple-mobile-web-app-title” content=”myApp” >

 


Follow these steps to create a GitHub Pages website without having to download anything

Step one is that you need craft and debug an HTML file locally on your own machine. Nothing fancy here – just open a text editor like NotePad and get rolling. An example of just such an app is here. You can use that if you want, but I would suggest you do this with your own code so you have the satisfaction of seeing your own creation as a web page anyone can access.

 Step two is that you store the file in a folder on your machine and rename it “index.html.” If it is any other name, it will not work on GitHub Pages.

Step three is make sure you have an account on GitHub. As of writing, this is totally free and requires no special software on your machine to get an account and manipulate GitHub right in your browser (stuff like Git that you have to download onto your machine can be learned later and are not necessary for this tutorial).

 Step four is create a repository on your GitHub account. Your webpage is basically just going to be a repository on your GitHub account. Just navigate to your GitHub account and click to create a new repository (aka “repo”). Just make sure the repo name is your GitHub user name plus “github.io” when you name it. My user name is olddognewtrix123, so when I made a repo that is supposed to actually be a webpage, I went on to my GitHub account, and clicked to create a new repo. When I was prompted to name the repo, I called it “olddognewtrix123.github.io.” If you do not name your repo correctly, all you will have created is just another GitHub repository. Which is great, but you won’t be able to hit it from your browser like a web page. So follow the exact naming convention. Leave the “Public” radio button selected. You can leave the “Initialize with ReadMe” checkbox unselected – it is not necessary. Now click the green Create Repo button.

 Step five is to click the Upload File button on the repository’s page. Select your index.html file from the folder on your machine and complete the upload. Fill out the comment fields and click the green Commit Changes button. You can repeat step three for any other files that your index.html file needs to run, like if you have a separate style sheet.

 Step six is super important and not a lot of tutorials mention it: you gotta make sure index.html has a ref tag, it is using the absolute path and not the relative path. So, click on the index.html file on the GitHub repository page. Once it is open you will see your HTML. Click the icon in the top right that looks like a pen to begin editing. Change any relative paths in your HTML to the absolute paths for the GitHub repository. So, if your HTML has
       <a href="/otherpage.html"/>
 you need to change it to 
    <a href="https://olddognewtrix123.github.io/otherpage.html"/>

Then of course commit your changes.

Step seven is simple – you wait. Sometimes it can take up to thirty minutes for your changes to show up on GitHub pages. After thirty minutes, plug the name of your repo (<yourusername>.github.io) into your browser. hit Enter, and bask in the glory of your new web page.