Progressive Web Apps: Das Web wird nativ(er)

Exercise 0

Make sure you have performed all steps described in the repository’s README file. Next, pull the changes found in the repository’s master branch by calling git pull on your command line or using your Git UI. If you are lost, git reset --hard will get you back on your journey.

Run ng serve on your command line. In the output, look for the line saying NG Live Development Server is running on … and open the URL shown there (usually http://localhost:4200/) in your browser. If you see a web site saying app works!, the app works.

If you haven’t yet, you might want to follow the speaker on Twitter.

Exercise 1

Next, we want to enable service worker generation and have a look at the differences before and after. Hence, run ng build --prod on your command line and check the build outputs in the dist folder relative to your project’s directory. The contents of the dist folder will be replaced on every new build, so make sure to either copy the directory listing or make a screenshot of the folder contents.

Now enable service worker generation by running this command: ng set apps.0.serviceWorker true

As a result, the serviceWorker property of the first entry in your .angular.cli.json will be set to true. Now run ng build --prod again and compare the results.

Note: When you are starting a new CLI project, you have to add a dependency to @angular/service-worker. The author was so kind and added this dependency for you.

Exercise 2

In order to be detected by search engines, your app needs a manifest.json. If you want to qualify for an app banner, you have to meet some requirements.

Create a new manifest.json and assign the required properties for an app install banner to be shown. You may also refer to the documentation found in Mozilla’s Development Network. Add an image of your choice (144×144 pixels in size) to the project (you can find a suitable image in the assets folder). Don’t forget to reference the manifest in your index.html.

{
  "short_name": "",
  "name": "",
  "icons": [
    {
      "src": "",
      "sizes": "",
      "type": ""
    }
  ],
  "theme_color": "",
  "start_url": "",
  "display": ""
}

Note: Files found in the src/assets folder will be copied automatically to the destination folder. For the manifest.json, you have to extend .angular.cli.json to include this file (add a new entry to the assets array below favicon.ico).

Optional: Run ng serve --prod and test your app using the Lighthouse Chrome extension. Access your app on your Android tablet or phone and try to add it to the home screen.

Exercise 3

Our service worker is active now. Run ng serve --prod, navigate to http://localhost:4200 and open the Google Chrome Developer Tools (F12 or ⌘⌥I). Investigate the options in Applications > Service Worker. Tick the “Offline” check box and reload the page (maybe twice). Does it work as intended?

Exercise 4

Add a file called ngsw-manifest.json to the src directory. The extended Webpack build process will pick this file up and merge it with the file generated during your project’s build. The Angular Service Worker can be configured using this file. Set the following content in order to get offline availability working even for the “empty” route and other application routes.

{
  "routing": {
    "index": "/index.html",
    "routes": {
      "/": {
        "prefix": false
      }
    }
  }
}

Exercise 5

Now let’s prepare our Progressive Web App for push notifications. Luckily, the Angular Service Worker already supports this. To enable push notifications, extend the ngsw-manifest.json as follows:

  "push": {
    "showNotifications": true,
    "backgroundOnly": false
  },

The exact steps required to add support for push notifications depend on the runtime platform. In order to use push messaging in Chrome, you will have to create a Google Cloud Messaging API key. Use Android App as a platform and enter an arbitrary namespace. Note down the sender ID and the server API key. In your manifest.json, add a new property and enter your sender ID there:

{
  // ...
  "gcm_sender_id": "<Sender ID>"
}

Next, we have to subscribe for push notifications. This can be done by injecting a reference of the Angular Service Worker into the constructor of the AppModule:

  constructor(serviceWorker: NgServiceWorker) {
    serviceWorker.registerForPush()
      .subscribe(registration => console.log(JSON.stringify(registration)));
  }

In this scenario, we’ll just log the registration to the console. In production scenarios, you would send the information to your backend or a third-party service. Using the information from the console, you can now send push notifications to your application or device.