How to simply build a PWA with Angular Service Worker

09.06.2021 Tom Trapp
Mobile angular typescript foss javascript frontend framework handson tutorial howto

What is a Progressive Web App?

A so-called Progressive Web Application, or PWA for short, describes a website that has special capabilities and properties to be as close as possible to a natively installed application.

For example for PWAs are:

  • offline availability
  • can be started from the smartphones homescreen or desktop of choice
  • able to send push notifications even though PWA is running in the background

Support for PWA-enabled browsers has been around since 2018, back then with the Google Chrome version 73. In 2021, Chrome announced that it would completely abolish so-called Chrome Apps by June 2022. A Chrome app is not a PWA, but rather a packaged web app. The concept of a PWA, however, is very similar. Since then, Google itself has recommended converting Chrome apps into PWAs and thus migrating from previous Chrome apps, as this standard will expire. The big goal was to replace mobile applications with installable PWAs and thus enable a hybrid single-track development and maintenance of an application. With Google, PWAs can even be listed directly in the Google Play Store and installed from there, analogous to a normal native app.

In general, a PWA offers numerous advantages over a mobile app:

  • easier updates (no dependencies to third-party app stores)
  • no updates or installation required
  • searchable via the Google search engine
  • easy ways to send links
  • cheaper development, since desktop and mobile are bundled

One would therefore assume that the PWA development is pushed everywhere for cost and maintenance reasons. Unfortunately, one or two native apps are still considered a 'symbol of status'. Unfortunately, what the future will bring cannot be said exactly, the great breakthrough of PWAs has been reported for years – which unfortunately has not yet materialized.

An example of a PWA?

A great example of what a PWA can do is Starbucks' official website: app.starbucks.com . This is the Starbucks WebShop. There is the possibility to order coffee or the like directly online and pick it up in a branch of your choice. Everyone knows the problem – you are on the go, want to order something quickly and first have to laboriously download a very large, i.e. memory-intensive app from the app or play store in order to benefit from the provider.

According to reports, the Starbucks PWA is 99.84% smaller in terms of memory footprint than the existing iOS app, making quick coffee ordering a lot easier and more enjoyable. After the launch of the PWA, Starbucks recorded a large increase in orders via the PWA, whether on mobile or desktop.

The technology behind a PWA?

The central point of a PWA is a so-called Service Worker, which acts as a kind of proxy between the frontend and the backend. With every request, this component checks whether a) you are online and b) whether a new version of the page is available in the backend. If you are offline or if there is no new version available, the service worker delivers the page as well as JavaScript, CSS and other web resources from the cache and the effective data from a browser-internal IndexDB.

This technique can be applied to almost all current web pages via JavaScript, frameworks such as Angular or similar. offer complete libraries for the PWA functionalities.

Angular PWA Service Worker Theory

PWA in Angular

How exactly does the whole construct around PWA and Service Worker, SW for short, work in Angular?

Here, too, Angular offers a very simple but powerful way to create a PWA, the @angular/pwa package. This package implements the complete Servic Worker functionality in an Angular project, it is important to know that the Service Worker is retained even after the page is closed. In this way, the next time the Angular PWA is called, the browser can obtain all resources etc. from the cache via the service worker. The cached version is then delivered via the service worker until the software notices that there is a new version of the application on the server. Angular uses a manifest file with the name ngsw.json for this, which is a generated file and information for the SW. The service worker uses this manifest file to find out about updates, among other things; it is called up every time the application is refreshed.

To-do list app as a PWA

But now we want to do a Deep-Dive in practice and convert our well-known b-nova-ToDo application into a PWA. Not many steps are necessary for this, as Angular offers the @angular/pwa package, which provides all the necessary files, configurations, etc.

First we would have to install a small local HTTP server, as the PWA functionality is not automatically activated via, for example, ng serve:

npm install http-server -g

Now that we have prepared the server, we add the PWA Angular Package to our application, as in previous blog posts in this series, we use the Angular CLI here:

ng add @angular/pwa --project b-nova-todo-list

Now our b-nova ToDo list is ready to be built and started as a PWA. The PWA functionalities are only activated with a productive build:

ng build --prod

Last but not least, let's start our finished Angular project with the previously installed HTTP server:

http-server -p 8080 -c-1 dist/b-nova-todo-list -o

Is that already a PWA?

Justified question, when you call up the page you do not notice any changes at first glance, and you do not notice any of the advantages. If you take a closer look, you can see a small new icon in the address bar of the browser (hier Google Chrome):

If we click here, the browser tells us that we can install an application here, this is the first big feature of the PWA.

Angular PWA Service Worker Install Icon

As soon as we have installed the PWA, we can put the icon on the desktop and run the application overhead without a browser, analogous to a natively installed application – cool, right?

Angular PWA Service Worker b-nova To Do PWA

If you take a closer look, you will find an entry 'Service Workers' in the Google Chrome Developer Tools in the ' Application' tab. Here we see more information about our currently installed service worker, there is also an exciting ' offline' checkbox.

Angular PWA Service Worker Google Chrome Menu

This 'offline' checkbox can be used to simulate and test the offline functionality of the PWA. As you can now see, our ToDo application is also fully functional in offline mode, the changes or new entries are saved in the browser's Local Storage.

Now let's go a step further and stop our HTTP servers. Now the application has virtually failed and can no longer be called. Fortunately, the service worker helps, and here too, both the web application in the browser and the installed PWA are still fully usable without an HTTP server!

Service Worker & Rest API

Last but not least, we want to make it a tick more exciting, we are implementing a REST endpoint and making it offline-capable. Of course, we need a REST backend first, here we use the NPM package mock-rest-server:

npm i -D mock-rest-server

Then we start the REST server:

node_modules/.bin/mock-rest-server

And now we have to fill it with initial data:

curl -X POST -d '{"title":"Awesome news!","body":"Some content."}' http://localhost:3000/v1/articles
curl -X POST -d '{"title":"Awesome news!","body":"Some more content."}' http://localhost:3000/v1/articles

Call Rest API

For the sake of simplicity, we implement the call of the remainder of the endpoint directly in the component:

The Service Worker can be configured in the so-called ngsw-config.json file.

#to - dos - component.ts

data:any[] = [];

...

ngOnInit()
:
void {
    this.toDos = this.toDoService.getToDos();
    this.http.get<any[]>("http://localhost:3000/v1/articles")
        .subscribe((fetchData: any[]) => {
            this.data = fetchData;
        })
}

Here we first create an array and then fill it in the ngOnInit method. As we learned in Angular Profi Tipps you should use a service architecture with dedicated model classes.

Now we have to output the requested data in the view, for this we simply add the following line to the end of the markup:

#to-dos-component.html

<br><br>
<div *ngFor="let item of data">
	<p>{{item.title}} | {{item.body}}</p>
</div>
</div>

If we start our application again as a PWA as described above, we see our sample content on the page.

If we now switch off our remaining servers or simulate offline operation of the PWA, we get errors when calling our remaining endpoint and the data is missing from the display.

Configure service worker

We don't want this state, however, the service worker should use the last cached version of the data before the REST endpoint has failed, or we have gone offline.

We can achieve this with a so-called dataGroups configuration in the ngsw-config.json. A dataGroups reflects a resource that is not managed by Angular, such as our REST endpoint.

We add the following definition to the end of the JSON object:

,"dataGroups": [
{
"name": "articles",
"urls": ["/v1/articles"],
"cacheConfig": {
"maxAge": "20s",
"maxSize": 5
}
}
]

With this we tell the service worker that the URL /v1/articles should be cached for a maximum of 20 seconds. This now means that a call is made to the REST endpoint only every 20 seconds and not at all, as before, every time the page is called.

If we now run a productive build again and start our HTTP server, we see the data as normal. A look at the Network tab shows that the data will only be retrieved again after the 20 seconds cache duration has expired.

Angular PWA Service Worker Network Calls

The small number wheel on a request indicates that the call is effectively against the outside and not against the service worker.

If we stop our rest of the end point and symbolize a failure, we only notice the failure after the 20 seconds have elapsed and the application has been reloaded.

Finally, one can say ...

that PWAs are great! 😀

By using a Progressiv Web App in combination with Angular, a website or application can be seamlessly presented and used on all end devices. Even at second glance, there are hardly any disadvantages or reasons against it. Do you have an application or a website that you want to modernize and deliver as a PWA? Contact us. Stay tuned!


This text was automatically translated with our golang markdown translator.

Tom Trapp - problem solver, innovator, athlete. Tom prefers to work on modern software all day long and attaches great importance to objectively clean, lean code.