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.
To follow along with this tutorial, you are going to need two things.
- Angular command line utility called
@angular/cli. (I am using version
- Lighthouse Chrome Extension
That’s all you need to build a PWA and to understand this tutorial. So let’s get started!
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.
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.
@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
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.
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
Then we inject an
Observable from the library
rxjs library is gives us the ability to use
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.
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.
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!
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
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.
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
Angular also installs two new dependencies which you can find inside the
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
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 👇