Learn to Build a Simple Progressive Web App (PWA) with Angular and Lighthouse — Hacker News Clone

How to build a simple Hacker News clone PWA with Angular and Lighthouse , step-by-step.

In this tutorial, I will show you step by step how to build a Progressive Web Application using Angular.

A Progressive Web Application is a performance focused web application that is streamlined for a mobile device. A PWA can be saved over a device’s Home/App screen and try to implement a native app feel and look.

The first PWA that really impressed me was Lite Twitter. They even support push notifications and offline support.

Quickly: Progressive Web Apps vs Native Apps

A Progressive Web App can have similar capabilities of a native mobile application. Mobile devices that run Android already have a powerful web browser, Google Chrome, pre-installed. A PWA app can provide a similar experience to that of a native application through the browser alone. Nowadays, some PWAs such as Twitter Lite or Facebook Lite even appear in the app stores.

Another notable difference between a PWA app and a native mobile application is that a PWA is deployed and accessible from web servers using a URL. Most PWAs still work in this way.

Requirements

To follow along with this tutorial, you are going to need two things.

  • Angular command line utility called @angular/cli. (I am using version 6.1.2.)
  • Lighthouse Chrome Extension

That’s all you need to build a PWA and to understand this tutorial. So let’s get started!

Installing Lighthouse

Lighthouse is an open-source tool created by Google which is used to audit websites and applications alike for accessibility performance, PWA features, and SEO. There are various ways to run this tool, such as from command line or as a browser extension. Lighthouse runs a series of audits against the URL of your application and, on completion, generates a report on how well the page performed.

With each audit, Lighthouse also provides reference to the documentation explaining what the audit summary and how to fix a problem in case of failure. You can then share these auditing reports in many ways such as in JSON format or as Github Gists.

Below is an example of how Lighthouse generates an auditing report.

To install this tool, I am going to add it as a Chrome Extension. You can download it here. Once installed, you will notice that a new icon appears in the extension bar like below.

On the top-right corner in Chrome Extension

With Lighthouse installed, we can now move ahead and install our next necessary tool, Angular CLI

Installing Angular CLI

In this section, I am going to show you how to install Angular CLI and then generate a project. Open your terminal.

Please note that Angular-CLI requires you to have a Nodejs installed with a version equal or greater to 8.9.x. Make sure you have the required version or above. To check which node version you currently have on your local machine, you can run node -v command.

After the @angular/cli has installed successfully, let us generate a new project. Run the following command and traverse into the newly created project directory.

This will create a project that has a structure looking like below.

Creating The Application

In the previous section, we generated our project directory, so now let’s run the default boilerplate application that comes with @angular/cli. Run the below command from your terminal.

The default app will run on URL: http://localhost:4200. See the below screenshot.

This verifies that everything from npm has been installed correctly.

Setup an HTTPClient

Now let us set up our Angular app to make it work first before I show you how to audit it with Lighthouse.

We are going to use a third party API and, to integrate that API, we are going to use HttpClientModule to send the HTTP requests. Import the module in the application inside the file src/app/app.module.ts.

This enables us to inject and use HttpClient in any Angular component in our app.

Creating an API Service

Let’s now create a service that fetches the data from a third party API we are going to use in our Angular app. To create a new service from command line please type the below in your console or terminal.

The g flag stands here for generate. This creates two new files inside src/app. We need to work with api.service.ts. Edit the file and add the below code. Inside this file, we start by importing HttpClient.

Then we inject an Observable from the library rxjs (which stands for Reactive Extensions for JavaScript). This allows us to handle asynchronous calls to the API from our app. We can use it with HTTP module to handle AJAX requests. This is a common programming pattern among Angular developers and is called Reactive Programming.

The rxjs library is gives us the ability to use Observable as the part of the JavaScript language until it becomes a native type of the language itself.

After importing the necessary dependencies, declare an Item interface that represents a single item of the returned JSON data. For demonstration purposes, I am using the Hacker News API. It is CORS enabled. The API gives us a lot of data but we only need a few things from it. You can test the API URL https://api.hnpwa.com/v0/news/1.json in any REST client to see what the results.

To create an injectable service class, we use the syntax @Injectable. Inside it, we provide providedIn: 'root' to tell the Angular app that this service we are declaring is created by the app root injector.

The function getData() above uses HttpClient injected in the constructor as httpClient. It calls the get() method of HttpClient for sending an HTTP GET request to the JSON endpoint. Furthermore, it returns an observable that we are going to use in the next to subscribe to it.

Consuming the API Service

Open the file app.component.ts and import the ApiService as below.

As you can see, we are also importing the class interface Item from the api.service.ts file. Every component in Angular has a life-cycle. Angular creates and renders the component as well as creates and renders a child copmonent before removing it from DOM. ngOnInit and OnInit represent the life-cycle hook that handles the fetching of data from the API after the AppComponent is initialized.

fetchData() is the function that calls the getData() function, defined in the file api.service.ts. You will notice that since getData() returns an observable and further allows us to subscribe to whatever result it comes with inside fetchData(). Finally, we are assigning the data to an items array.

Building the UI

The purpose of this tutorial is to teach the concepts that lead to building a PWA using Angular. Since this is only a demo, I am going to keep it the UI simple. I am not going to use any third party UI library. However, you can make it look as awesome as you want or use a third-party library if you want to.

In the previous section we wrote the code for fetching the data from the API endpoint.

But how do we know that the data is being fetched?

You may have noticed that I added one console statement to see if we are getting the data. Open Chrome browser and make sure the npm start command is running from your terminal. Go to Developer Tools and go to Console tab. You can see here if there are any errors with data being fetched.

We only need a few fields as we defined in the class interface Items. However, the API endpoint gives all data fields that you can use to build a complete HackerNews app clone, complete with data!

Open up app.component.html add the following markup.

The incoming data from the JSON API endpoint is in an array of objects. To display the fields such as the title of each post and the URL of same, we are going to traverse the array using *ngFor* as the attribute to the unordered list element. I am also adding basic CSS styles so do add them inside app.component.css.

We only need one component file for our app since there is not much going in our app UI wise. If you take a look at the http://localhost:4200 you will see something similar.

Our demo app is ready, now all we need is to convert it into a Progressive Web Application.

Building the PWA

After building the web application when you start to convert it to a Progressive Web App, you will have to build for production. Most PWA features are not compatible in development mode. You cannot trigger the execution of service workers, caching, use HTTPS etc. To build our current Angular application for production we have to run the following command from the terminal.

This will create a dist/ng-pwa-demo/ directory in the root of our Angular project. We will use an npm tool like serve to the serve the content inside the dist folder without setting up the backend. Install this tool from npm.

Then traverse into dist/ng-pwa-demo/ from the terminal and type the below command.

From the web browser you can navigate to http:localhost:5000/ to see the result. Now let us first audit and see what is missing or what steps we need to take to convert this app into a PWA.

Go to the developer tools in the Chrome Browser and click on the Audits panel. First, choose Mobile instead of Desktop and then choose Progressive Web App option only. Uncheck everything else as we are going to run the audit only for a PWA. Lastly, hit the Run audits button. Once the process of auditing is complete, it will generate a report and showcase it to you like below.

Lighthouse performs various checks to validate different aspects of a Progressive Web App. These aspects and more details about each of them are mentioned at PWA Checklist. This guide not only covers the basics and details about the different PWA terminology but also offers a way to fix them.

We are getting an initial score of 46 and four of the audits are currently being passed. Our Angular app currently fails in 7 other audits related to no value of brand theme color provided, registration of a service worker, redirect from HTTP traffic to HTTPS, etc.

Angular CLI allows you to add PWA features to an existing application by running a simple command from the terminal described below.

This command automatically add basic configuration required for an angular app to turn into a PWA and starts by creating a new file called manifest.json, adding different sizes of icons as assets and registering a service worker inside the file called ngsw-config.json. After that, run the production build command again.

This command will register and include all the necessary files inside the dist directory. A manifest.json file looks like this:

This is how our latest dist directory looks like.

To change the icons or assets related to our PWA, you can always traverse to assets/icons folder in the src directory. After you have added your own app icons for the sizes mentioned inside the manifest.json file you can run the ng build command again.

The ngsw-worker.js file contains the service worker. To insert the service worker and let our angular app know about its existence is present and appended when we converted the command to turn our angular app into a PWA inside src/app/app.module.ts file.

Angular also installs two new dependencies which you can find inside the package.json.

The service worker is automatically enabled inside the file angular.json which contains the configuration information from the start, when we created this application. Also, inside dist/ng-pwa-demo/index.html file you will find two lines added.

The manifest attribute is linking the manifest.json and index.html. The theme color tells the browser to show which color such as in the address bar.

You see how much PWA configuration Angular CLI takes care of with just one command. Imagine, adding all that details manually in every file we have seen or mentioned in this section! I can say for myself, I will surely miss something or other until the next audit breaks or fails.

With that, now let us run another audit and see how far we have reached. This is the latest audit report I have generated.

11 audits are being passed! The only one which is failing right now is related to HTTPS. That is the reason our current score is 92. Once you host this app on deployment server such as Firebase which is secured by default since it uses HTTPS, you will be able to configure HTTPS and then all of the audits will pass.

You can find the complete code for this PWA demo at the Github repository below 👇

Starting a new Angular project? Looking for an Angular developer?

Crowdbotics helps business build cool things with Angular, and among other things. If you have a project where you need additional developer resources, drop us a line. Crowbotics can help you estimate build time for given product and feature specs, and provide specialized developers as you need them. If you’re building with Angular, check out Crowdbotics.