Create a progressive web app

You can convert the Oslo sample site into a Progressive Web Application (PWA). Progressive Web Applications are applications that are hosted like regular web applications and offer benefits such as availability on the home screen and offline support similar to native applications. Unlike regular applications, you do not have to install or add PWAs to the app store. Content is a great environment to host and develop PWAs as it supports hosting applications through HTTPS, which is a basic requirement for PWAs. The following tutorial demonstrates how to convert the Oslo sample to a PWA.

Before you begin

To get started, you need:

Install your dependencies

  1. Update the version of @angular/cli in your /package.json file to ^6.1.5:
"devDependencies"
: {
    
"@angular/cli"
: 
"^6.1.5"
,
}
  1. Update all references to @ibm-wch-sdk/... in your /package.json to at least 6.0.341.
  2. Install the dependencies by calling npm install.
  3. Verify your install by calling:npx ng --version

This returns something like the following information:

Angular CLI: 6.1.5
Node: 8.11.2
OS: win32 x64
Angular: 6.1.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.7.5
@angular-devkit/build-angular     0.6.8
@angular-devkit/build-optimizer   0.6.8
@angular-devkit/core              0.6.8
@angular-devkit/schematics        0.6.8
@angular/cli                      6.1.5
@ngtools/json-schema              1.1.0
@ngtools/webpack                  6.0.8
@schematics/angular               0.7.5
@schematics/update                0.7.5
ng-packagr                        3.0.6
rxjs                              6.2.2
typescript                        2.7.2
webpack                           4.8.3
  1. Update /src/app/Constants.ts to point to your tenant:
export
class
Constants {
  static
readonly DOMAIN_NAME =

'%YOUR_HOSTNAME%
'
;
  static
readonly CONTENT_HUB_ID =

'%YOUR_TENANT_ID%
'
;

  ...
}

Add PWA support

Angular comes with a command to add PWA support to your application.

  1. Run the following command to add PWA support npx ng add @angular/pwa --project=wch-site-application.
  2. Verify your installation by calling:npx ng --version.

This returns something like the following information:

Angular CLI: 6.1.5
Node: 8.11.2
OS: win32 x64
Angular: 6.1.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router, service-worker

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.8
@angular-devkit/build-angular     0.6.8
@angular-devkit/build-optimizer   0.6.8
@angular-devkit/core              0.7.5
@angular-devkit/schematics        0.7.5
@angular/cli                      6.1.5
@angular/pwa                      0.7.5
@ngtools/json-schema              1.1.0
@ngtools/webpack                  6.0.8
@schematics/angular               0.7.5
@schematics/update                0.7.5
ng-packagr                        3.0.6
rxjs                              6.2.2
typescript                        2.7.2
webpack                           4.8.3
  1. Add the src/assets folder to your angular.json file:
{
  
"projects"
: {
    
"wch-site-application"
: {
      
"architect"
: {
        
"build"
: {
          
"options"
: {
            
"assets"
: [
              
"src/oob-spa"
,
              
"src/favicon.ico"
,
              
"src/manifest.json"
,
              
"src/assets"

            ]
          }
        }
      }
    }
  }
}
  1. Edit the file src/app/app.module.ts and modify by removing the following line (but leave the import from './environment/environment')
import { environment } from

'../environments/environment'
;
  1. Edit the file environment/environment.ts and disable polling in the httpOptions:
export
const environment = {
  ...,
  httpOptions: {
    pollTime: 999999,
    retries: 5,
    
/** add this */

    usePolling: false,
    useBootstrap: false,
    useLocalStorage: false,
    useStaticResources: false
  }
};

Configure your PWA

In the next step, configure the resources that will be cached by our application, so it can work offline.

  1. Make the following changes to the ngsw-config.json file
  • Add the used web fonts to the assetGroups section. In Oslo, these fonts are referenced in the index.html file directly. Change the URLs if your application uses different fonts or additional external resources:
{
  
"assetGroups"
: [
    {
      
"name"
: 
"app"
,
      
"urls"
: [
        
"https://ajax.googleapis.com/ajax/libs/webfont/**"
,
        
"https://fonts.googleapis.com/**"
,
        
"https://fonts.gstatic.com/**"

      ]
    }
  ]
}
  • Configure the API URLs that our application uses and that we want to cache. For this purpose, make sure to locate the API URL for your tenant. In our example, we use https://%YOUR_HOSTNAME%/api/%YOUR_TENANT_ID% for the API URL and https://%YOUR_HOSTNAME%/%YOUR_TENANT_ID%/ for the delivery URL.
  • Add a dataGroups entry and configure the caching:
{
  
"dataGroups"
: [
    {
      
"name"
: 
"Oslo"
,
      
"urls"
: [
        
"https://%YOUR_HOSTNAME%/%YOUR_TENANT_ID%/**"
,
        
"https://%YOUR_HOSTNAME%/api/%YOUR_TENANT_ID%/**"

      ],
      
"cacheConfig"
: {
        
"strategy"
: 
"performance"
,
        
"maxSize"
: 1000,
        
"maxAge"
: 
"10h"
,
        
"timeout"
: 
"5s"

      }
    }
  ]
}
  1. Edit the file angular.json and add the baseHref field to your build. This field is the deliveryURL of your tenant without its origin. In our example, the delivery URL is https://%YOUR_HOSTNAME%/%YOUR_TENANT_ID% so we use /%YOUR_TENANT_ID%/ as the baseHref. Make sure that the value starts and ends with a slash.
{
  
"projects"
: {
    
"wch-site-application"
: {
      
"architect"
: {
        
"build"
: {
          
"configurations"
: {
            
"production"
: {
              
"baseHref"
: 
"/%YOUR_TENANT_ID%/"
,
              ...
            }
          }
        }
      }
    }
  }
}
  1. Edit the src/index.html file and remove the first script section:
<!doctype html>
<html
lang=
"en"
>
<head>
    
<!--

	<script type='text/javascript'>
		var possibleTenant = document.location.pathname.split('/')[1];
		console.warn('index.html: possible tenant is %o and base url is %o', possibleTenant, possibleTenant.search(/\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}/) === 0 ? '/' + possibleTenant + '/' : '/');
		var baseUrl = possibleTenant.search(/\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}/) === 0 ? '/' + possibleTenant + '/' : '/';
		document.write('<base href="' + baseUrl + '">');
    </script> -->

</head>
</html>
  1. Edit the src/manifest.json file and update the scope and start_url fields to point to your delivery URL:
{
  
"scope"
: 
"/%YOUR_TENANT_ID%/"
,
  
"start_url"
: 
"/%YOUR_TENANT_ID%/"

}

Additional performance optimization

Preload font files for better performance. Edit the file src/index.html and add the following line:

<!doctype html>
<html
lang=
"en"
>
<head>
  
<!-- add this -->

  <link
rel=
"preload"

href=
"https://fonts.googleapis.com/css?family=Vidaloka%7CRoboto"

as=
"style"

crossorigin=
"anonymous"
>
</head>
</html>

Build and deploy your application

Run the following command to build and deploy your application.
npm run build-deploy-code
In addition, run the following command to flush the Akamai caches, otherwise it takes about 11 m until your changes become active.
npm run clear-cache

Test PWA Support

Use Lighthouse in the Chrome browser to test your application.

Expected outcome

The result must be 100% coverage of the PWA Checklist.