© Majid Hajian 2019
Majid HajianProgressive Web Apps with Angularhttps://doi.org/10.1007/978-1-4842-4448-7_6

6. An App Manifest and Installable Angular App

Majid Hajian1 
(1)
Oslo, Norway
 

Up until this point in the book, we have focused on the core feature of Progressive Web App (PWA), Service Worker. It enables us to cache our static assets as well as dynamic content. The app will continue to work offline, which is especially important on mobile devices. However, an app’s “look and feel” is another important factor that enhances the user experience to truly delight users.

In this chapter, we focus on visual appeal and a few different ways that can help boost engagement on the app. We explore features such as Add to Home Screen and customization, which prompts a user to add the web to their device home screen.

The Web App Manifest

The Web App Manifest is a JSON text file following Web App Manifest specification that provides information about an application such as its name, author, icons, and description. But more importantly, this file enables an application to be installed by a user on their device and allows us to modify the theme, URL that should be opened, splash screen, icons on home page, and more.

Let’s take a look at manifest.json located in /src/, which Angular CLI has created by default.
{
  "name": "lovely-offline",
  "short_name": "ApressPWA",
  "theme_color": "#1976d2",
  "background_color": "#fafafa",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

Most of the properties are self-explanatory, but I will try to provide descriptive definitions. Each property in a manifest file has a role and tells the browser information regarding our app’s look and feel. Although default manifest.json added by Angular CLI should be fine for most use cases, there are more properties that we can add to better enhance the user experience depending our needs and requirements.

Let’s break them down:
  • name:

    a readable name for the app displayed to user or as a label for an icon.

  • short_name:

    short name that replaces name if that doesn’t fit due to insufficient space.

  • theme_color:

    defines the default theme color for the application to tint OS or browser-related UIs: for example, browser’s toolbar or Android’s task switcher. HEX code or color’s name can be used.

  • background_color:

    defines the expected background color for the app even before user agent loads website style sheets. Usually, there is a short gap between launching the web application and loading the site’s content. This creates a smooth transition to fill the delay. You can use color HEX code or standard color’s name. Note that this background will not be used by the user agent after the style sheet is available.

  • display:

    preferred display mode for the website. Four options are available as per spec, but it may not be available in all browsers:

    fullscreen: All of the available display is used. if not supported, falls back to standalone mode.

    standalone: most browser elements are hidden. Feels like a standalone application. In this mode, the user agent will exclude UI elements for controlling navigation but can include other UI elements such as a status bar. If not supported, falls backs to minimal-ui mode.

    minimal-ui: this application looks like a standalone app; however, essential UIs of the browser are still visible such as navigation buttons. It not supported, fall backs to browser mode.

    browser: just conventional browser tab or new window.

    It’s interesting to know what there is a feature in CSS where you can detect display-mode. See code below:
    @media all and (display-mode: minimal-ui) {
      /* ... */
    }
    @media all and (display-mode: standalone) {
      /* ... */
    }
  • scope:

    more or less similar to service worker scope that defines the navigation scope of this website’s context. If a page is outside of this scope, it retunes to a normal web page inside a browser tab/window. In case of relative URL, the base URL will be the URL of the manifest. If omitted, default is everything under the manifest directory and all subdirectories.

  • start_url:

    the URL that loads when a user launches the application. It can be different from the main page, for example, if you want your PWA users to go directly to login page or signup page instead of home page. For analytical purposes, start_url can be crafted to indicate that the application was launched from the outside of the browser, which can be translated to PWA. That is: "start_url": "/?launcher=homescreen"

  • icons:

    an array of image files that specifics the app icons depending on the context. Each image has three properties:

    src: path to the image file; in case of relative URL, the base URL will be the URL of the manifest.

    sizes: specifies an icon size (even multiple sizes that are containing space-separate image dimensions). There are a variety of different screen sizes that we should support; the more dimensions we include, the better result we will get regarding the quality of icons.

    type: the media type1 of image; if the user agent doesn’t support this type, they can quickly ignore it.

  • prefer_related_applications:

    this asks the browser to indicate to the user a specified native application in which are recommended in the next property, over the PWA. Although it may sound silly, sometimes it happens that we have a very specific native feature that doesn’t exist on the web, so we want our user to use a native app instead. If omitted, the default value is false.

  • related_applications:

    recommended native applications that are installable or accessible from underlying platform store. For example, link to an Android app from Google Play Store. The objects may contain platform, url, and id.
    {
        "platform": "play",
        "url": "https://play.google.com/store/apps/details?id=com.example.app1",
        "id": "com.example.app1"
      }, {
        "platform": "itunes",
        "url": "https://itunes.apple.com/app/example-app1/id123456789"
      }
  • orientation:

    sets the app work on default orientation. Orientation may be one of the following values:
    any, natural, landscape, landscape-primary, landscape-secondary
    portrait, portrait-primary, portrait-secondary
  • dir:

    specifies the primary text direction for the name, short_name, and description. There are two values: ltr, auto, and rtl. When the value is omitted, default is auto.

  • lang:

    together with dir, it specifies correct display language. Default is en-US.2

  • description:

    a general description of what the website does.

  • serviceWorker:

    this member represents an intended service worker registration in form of a registration object.
    "serviceworker": {
      "src": "sw.js",
      "scope": "/foo",
      "update_via_cache": "none"
    }
This feature may not work in any browsers.
  • categories:

    specifies an array of strings of the expected application categories to which the web application belongs, written in lowercase.

  • screenshots:

    array of image resources that represent the web application in common usage scenarios. This might not work yet in any browser or platform.

  • iarc_rating_id:

    represents the International Age Rating Coalition (IARC)3 certification code of the web application.

To reference a manifest file, we need to add a link tag between head to all the pages in our web app. However, we have a single page application with Angular, and ng-cli has added the link to index.html and angular.json to copy this file to the root folder after build.
// index.html where we added manifest.json link.
<head>
.
.
  <base href="/">
  <link rel="manifest" href="manifest.json">
.
.
 </head>

Debugging Web App Manifest

Now that I have covered the Web App Manifest and referenced the index HTML page, we should be able to run an application and then navigate to the app in the Chrome. In DevTools, go to Application tab and click on manifest option on the left side, right above Service Workers (see Figure 6-1).

The details appear there, including errors if any. There is an option to test the prompt to add the app to the home screen also.
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig1_HTML.jpg
Figure 6-1

App manifest details in DevTools

Although Chrome DevTools is fine to debug your manifest file, there are tools that you can check to validate your manifest file against W3C spec. One example is manifest-validator.appspot.com where you can simply audit your manifest file. Figure 6-2 shows a screenshot of Web Manifest Validator.
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig2_HTML.jpg
Figure 6-2

Web Manifest Validator is a tool where you can debug your manifest file

Adding to Home Screen

By default, a native app installs on your home screen. You will see an icon and short name, and when you need to run this application, it’s easy to come back to the home screen and tap on the icon to open up the app. As web developers, it is important to engage our users and keep them coming back to our app. So, functionality as a native app is one piece of the puzzle to tackle engagement. A great way to seamlessly allow our users to add our web’s app to their home screen is Add to Home Screen (you may see A2HS) capability, also known as a web app install banner.

This feature makes it easy to install a PWA on the mobile or desktop device. It displays a prompt and after the user accepts it, your PWA will added to their launcher or home screen. It will run like any other installed app and looks similar to native apps.

However, the web app install banner prompt will not be shown unless otherwise it meets the following criteria:
  1. 1.

    Serve over HTTPS (this was one of the PWA core concepts and required for Service Worker).

     
  2. 2.
    Web App Manifest has to include:
    1. a.

      short_name or name

       
    2. b.

      icons must include a 192px and a 512px sizes icons

       
    3. c.

      start_url must have a proper value

       
    4. d.

      display must be one of the: fullscreen, standalone, or minimal-ui

       
     
  3. 3.

    The web app is not already installed.

     
  4. 4.

    An appropriate user engagement heuristic.

    This item may change over time, so you should always keep yourself updated with the latest news and check different browsers’ criteria lists time to time. At the time of writing this book, a user must interact with the domain for at least 30 seconds.

     
  5. 5.

    App has a registered Service Worker with a fetch event handler.

     

While this list is in a bit of flux and is updated frequently, if these criteria are met, Google Chrome will fire an event called beforeinstallprompt that we should use it to show the prompt to our user. Keep an eye on different browsers and check the latest news to see if they support this event or similar events.

Although Safari does not support the automatic Add to Home Screen prompt or beforeinstsallprompt event , the manually add to home screen is shown by tapping the share button, even though it behaves a bit differently compared with other browsers. I hope that by the time you read this book, an automatic version of this feature will be supported by Safari and all other browsers.

Note

Chrome 67 and earlier showed an “Add to Home Screen” banner. It was removed in Chrome 68 and a dialog will be shown if it is listened to beforeinstallprompt and the user taps on an element that has a proper gesture event.

Handling Installation Event (Deferring the Prompt)

As we have seen, when all the criteria are met, beforeinstallprompt event fires on the window object. It is crucial to listen to this event to indicate when the app is installable, and we need to act accordingly on the web app to show an appropriate UI to notify our user that they are able to install this app on their home screen.

While add to home screen is our main goal, this event can be used for other purposes also, such as the following:
  1. 1.

    Sending user choice to our analytics system.

     
  2. 2.

    Defer displaying the notification until we ensure that’s the best time to show in which user will tap or click.

     
In order to save the event that has been fired, we need to write the code as the following:
let deferredPrompt;
window.addEventListener('beforeinstallprompt', event => {
  // Prevent automatically showing the prompt if browser still supports it
  event.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = event;
  // This is time to update UI, notify the user they can install app to home screen
  const button = document.getElementById('add-to-home-screen-button');
  button.style.display = 'block';
  button.addEventListner('click', () => {
    if (deferredPrompt) {
      // will show prompt
      deferredPrompt.prompt();
      // Wait for the user to respond to the prompt
      deferredPrompt.userChoice.then(choiceResult => {
        // outcome is either "accepted" or "dismissed"
        if (choiceResult.outcome === 'accepted') {
          // User accepted the A2HS prompt
          // send data to analytics
          // do whatever you want
        } else {
          // User dismissed the A2HS prompt
          // send data to analytics
          // do whatever you want
        }
         // we don't need this event anymore
        deferredPrompt = null;
        // delete or hide this button as it's not needed anymore
        button.style.display = 'none';
      });
    }
  });
});

It’s only possible to call prompt() on the deferred event once. If the user dismisses it, we need to wait until the browsers trigger beforeinstallprompt event on the next page navigation.

The Mini-Info Bar

The mini-info bar is an interim experience for Chrome on Android at the time of writing this book; it is moving toward creating a consistent experience across all platforms that includes an install button into the omnibox as shown in Figure 6-3.
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig3_HTML.jpg
Figure 6-3

The mini-info bar in Google Chrome on Android4

This is Chrome UI component and we are not able to control it. Once it has been dismissed by user, it will not appear again until a sufficient amount of time. Regardless of preventDefault() on the beforeinstallprompt event, if the website meets all the criteria above, this mini-bar will appear.

This experimental functionality may be controllable or completely eradicated in the future.

Implementing Functionality into Angular App

Let’s now implement the code above in our Angular sample project. Start off by creating a service called AddToHomeScreenService and import it to CoreModule.

This service will hold the prompt event and will share this event according to the modules.
@Injectable({
  providedIn: 'root'
})
export class AddToHomeScreenService {
  public deferredPromptFired$ = new BehaviorSubject<boolean>(false);
  public deferredPrompt;
  get deferredPromptFired() {
    this.deferredPromptFired$.next(!!this.deferredPrompt);
    return this.deferredPromptFired$;
  }
  public showPrompt() {
    if (this.deferredPrompt) {
      // will show prompt
      this.deferredPrompt.prompt();
      // Wait for the user to respond to the prompt
      this.deferredPrompt.userChoice.then(choiceResult => {
        // outcome is either "accepted" or "dismissed"
        if (choiceResult.outcome === 'accepted') {
          // User accepted the A2HS prompt
          // send data to analytics
          // do whatever you want
          this.sendToAnalytics(choiceResult.userChoice);
        } else {
          // User dismissed the A2HS prompt
          // send data to analytics
          // do whatever you want
          this.sendToAnalytics(choiceResult.userChoice);
        }
        // we don't need this event anymore
        this.deferredPrompt = null;
        this.deferredPromptFired$.next(false);
      });
    }
  }
  public sendToAnalytics(userChoice) {
    // for example, send data to Google Analytics
    console.log(userChoice);
  }
}
In the app.component.ts file, by adding @HostListener, we will listen to for a beforeinstallprompt event and by injecting AddToHomeScreenService, we have access to the deferredPrompt, which helps to keep our event object.
export class AppComponent implements OnInit {
  joke$: Observable<string>;
  @HostListener('window:beforeinstallprompt', ['$event'])
  onEventFire(e) {
    this.a2hs.deferredPrompt = e;
  }
  constructor(
 private db: DataService,
 private a2hs: AddToHomeScreenService
) {}
  ngOnInit() {
    this.joke$ = this.db.getRandomDadJoke();
  }
}

Next, I decided to show a notification box to my user on the notes list page. I think this is the best place to ask if the user would like to install the app since they have already benefited from the app, and it’s likely that they will accept the prompt. So, it’s good practice not to bother a user with an unwanted prompt or notification and ask them, instead, when it makes sense.

AddToHomeScreenService was injected to NotesListComponent and UI has been created accordingly.
export class NotesListComponent implements OnInit {
       isAddToHomeScreenEnabled$;
         constructor(private db: DataService,
       private a2hs: AddToHomeScreenService) {}
         ngOnInit() {
           // this.notes$ = this.db.getNotes();
           this.notes$ = this.db.initializeNotes();
           this.isDbLoading$ = this.db.isLoading$;
           this.isAddToHomeScreenEnabled$ = this.a2hs.deferredPromptFired;
         }
}
And in the notes-list.component.html file, at the top of the page, I will add a simple card to ask the user if they like to interact with prompt as soon as it it’s ready.
<mat-card *ngIf="isAddToHomeScreenEnabled$ | async">
  <mat-card-subtitle>Add To Home Screen</mat-card-subtitle>
  <mat-card-content>
    Do you know you can install this app on your homescreen?
    <button mat-raised-button color="primary" (click)="showPrompt()">Show me</button>
  </mat-card-content>
</mat-card>
<div *ngIf="notes$ | async as notes; else notFound">
  <app-note-card *ngFor="let note of notes" [note]="note" [loading]="isDbLoading$ | async" [routerLink]="['/notes', note.id]">
  </app-note-card>
</div>
<ng-template #notFound>
  <mat-card>
    <mat-card-title>
      Either you have no notes
    </mat-card-title>
  </mat-card>
</ng-template>

Put all of it together and build an application for production and then deploy to Firebase.

Adding to Home Screen on Mobile and Desktop

Now that we have implemented all the criteria, it’s time to test it on the mobile and desktop. Since Google Chrome has the best support for installing an app, you may ask what actually Google Chrome does when a user accepts the prompt?

Chrome handles most of the heavy lifting for us:
  1. 1.

    Mobile:

    Chrome will generate a WebAPK,5 which results in better integrated experiences for the users.

     
  2. 2.

    Desktop:

    Your app is installed and will run in an app window6 on both Mac and Windows machines.

     

Note

To test install flow for Desktop PWA on Mac, you’ll need to enable the #enable-desktop-pwas flag in Google Chrome. It may be the default in the future or when you are reading this book.

Let’s see this in action on a Mac and Android phone, as shown in Figure 6-4.
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig4_HTML.jpg
Figure 6-4

Notification is shown once beforeinstallprompt in Chrome on Android and Mac was fired

When you click on the button to show the prompt, a browser dialog prompt will appear (see Figure 6-5).
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig5_HTML.jpg
Figure 6-5

Prompt Dialog in Chrome on Mac

Once you click on Install, the app will have installed in Chrome Apps folder and will be ready to be served as a standalone app (see Figure 6-6). This feature is also available on Windows 10.
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig6_HTML.jpg
Figure 6-6

PWA was installed in Chrome apps on Mac

Microsoft Windows7

PWA in Edge is a first-class citizen. Once PWA was distributed through the Microsoft Store, the entire Windows 10 install base of 600+ million active monthly users are your potential app audience!

Interestingly, when PWAs are in Windows 10, they run as Universal Windows Platforms apps and will gain the following technical advantages:
  • Standalone window

  • Independent process from browser (isolated cache, less overhead)

  • No storage quota (for IndexedDB, local storage, etc.)

  • Offline and background processes Access to native Windows Runtime (WinRT) APIs via JavaScript

  • Appearance in “app” contexts such as the Windows Start menu and Cortana search results

One of the greatest features is the ability to access WinRT APIs. It’s just a matter of identifying what you need to use, obtaining the requisite permissions, and employing feature detection to call that API on supported environments (see Figure 6-7). Let’s look at one example:
if (window.Windows && Windows.UI.Popups) {
    document.addEventListener('contextmenu', function (e) {
        // Build the context menu
        var menu = new Windows.UI.Popups.PopupMenu();
        menu.commands.append(new Windows.UI.Popups.UICommand("Option 1", null, 1));
        menu.commands.append(new Windows.UI.Popups.UICommandSeparator);
        menu.commands.append(new Windows.UI.Popups.UICommand("Option 2", null, 2));
        // Convert from webpage to WinRT coordinates
        function pageToWinRT(pageX, pageY) {
            var zoomFactor = document.documentElement.msContentZoomFactor;
            return {
                x: (pageX - window.pageXOffset) * zoomFactor,
                y: (pageY - window.pageYOffset) * zoomFactor
            };
        }
        // When the menu is invoked, execute the requested command
        menu.showAsync(pageToWinRT(e.pageX, e.pageY)).done(function (invokedCommand) {
            if (invokedCommand !== null) {
                switch (invokedCommand.id) {
                    case 1:
                        console.log('Option 1 selected');
                        // Invoke code for option 1
                        break;
                    case 2:
                        console.log('Option 2 selected');
                        // Invoke code for option 2
                        break;
                    default:
                        break;
                }
            } else {
                // The command is null if no command was invoked.
                console.log("Context menu dismissed");
            }
        });
    }, false);
}
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig7_HTML.jpg
Figure 6-7

Context menu on Microsoft Edge and Windows App

Android and Chrome

Flow is similar for Chrome in Android. beforeinstallprompt event is triggered. Once we tap on the button that we implemented, the dialog will be shown (see Figure 6-8).
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig8_HTML.jpg
Figure 6-8

Install app notification to user and add to home screen dialog

As soon as the user accepts it to install, App icon and short_name will have been placed just next to other native apps icons in the home screen as shown in Figure 6-9.

Note

Samsung internet browser behavior is similar to Chrome but reacts slightly differently.

../images/470914_1_En_6_Chapter/470914_1_En_6_Fig9_HTML.jpg
Figure 6-9

App installed on home screen and once tapped to open, splash screen with configured background and icons is shown

When you tap to open the app, no browser chrome (navigation buttons, address bar, menu options, etc.) are visible with the fullscreen option, and you’ll notice that the status bar on the top adopts the theme_color, which we have configured in our app (see Figure 6-10).
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig10_HTML.jpg
Figure 6-10

PWA looks similar to native app once it opens

Manually Adding to Home Screen

Dialog prompt is not guaranteed to always be triggered. So, there are possibilities to manually add a PWA to the home screen. This feature is also available on Safari iOS.

In Chrome, if you click on menu context menu on the top-right side of the browser, you’ll see the menu options where you can find add to home screen, tap on it, and a prompt dialog UI appears.

In Safari, the add to home screen feature is hidden under the share button. You should explicitly hit share and then you’ll find add to home screen as shown in Figure 6-11. However, Safari doesn’t exactly follow the Web App Manifest spec and may be changed in the future – hopefully by the time you are reading the book.
../images/470914_1_En_6_Chapter/470914_1_En_6_Fig11_HTML.jpg
Figure 6-11

Add to Home Screen buttons are available on Safari and Chrome

Further Enhancement

There are a few tags available to refine UI in for Apple and Microsoft where web manifest is not supported. I add them to index.html between head tag. Even though it’s a minor improvement, we still progressively enhance our user experience, which is our goal in PWA.
  <!-- Enhancement for Safari-->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="default">
  <meta name="apple-mobile-web-app-title" content="ApressNote">
  <link rel="apple-touch-startup-image" href="/assets/icons/icon-512x512.png">
  <link rel="apple-touch-icon" sizes="57x57" href="/assets/icons/icon-96x96.png">
  <link rel="apple-touch-icon" sizes="76x76" href="/assets/icons/icon-72x72.png">
  <link rel="apple-touch-icon" sizes="114x114" href="/assets/icons/icon-114x114.png">
  <link rel="apple-touch-icon" sizes="167x167" href="/assets/icons/apple-icon-384x384.png">
  <link rel="apple-touch-icon" sizes="152x152" href="/assets/icons/apple-icon-152x152.png">
  <link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-icon-384x384.png">
  <link rel="apple-touch-icon" sizes="192x192" href="/assets/icons/icon-192x192.png">
  <!-- Tile icon for Win8 (144x144 + tile color) -->
  <meta name="msapplication-TileImage" content="/assets/images/icons/icon-144x144.png">
  <meta name="msapplication-TileColor" content="#3372DF">
  <meta name="msapplication-starturl" content="/">
  <meta name="application-name" content="ApressPWA">
  <!-- Mobile specific browser color -->
  <meta name="theme-color" content="#3f51b5">

apple-mobile-web-app-capable: behaves similarly to display fullscreen mode if set to yes. We determine whether a web page is displayed in fullscreen mode using the window.navigator.standalone in Safari.

apple-mobile-web-app-status-bar-style: this meta tag has no effect unless you first specify fullscreen mode as described in apple-apple-mobile-web-app-capable. If content is set to default, the status bar appears normal. If set to black, the status bar has a black background. If set to black-translucent, the status bar is black and translucent. If set to default or black, the web content is displayed below the status bar. If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar. The default value is default.

apple-touch-startup-image: specifies a launch screen image that is displayed while your web application launches. By default, a screenshot of the web application the last time it was launched is used.

apple-mobile-web-app-title: specifies a web application title for the launch icon. By default, the <title> tag is used.

apple-touch-icon:8 specifies an icon to represent your web application or web page that user may want to add to the home screen. These links, represented by an icon, are called Web Clips.

application-name:9 the default name displayed with the pinned sites tile (or icon).

msapplication-starturl: the root URL of the pinned site similar to start_url in web manifest.

msapplication-TileColor: sets the background color for a live tile.

msapplication-TileImage: specifies a URI for the desired image in the background image for live tile.

While you can add all of the enhancements manually yourself, there is a library from Google Chrome Team that can help you mitigate this issue automatically.

PWACompat Library10

PWAcompat is a library that brings the Web App Manifest to noncompliant browsers for better PWAs; you can use the PWACompat library where we will fill the gap for wider support in most browsers through legacy HTML tags for icons and theming. Basically, you just need to include the library script in your page and you are done!
<link rel="manifest" href="manifest.json" />
<script async src="https://cdn.jsdelivr.net/npm/[email protected]/pwacompat.min.js"></script>
What actually this library does is to update your page and also the following:
  • Create meta icon tags for all icons in the manifest (e.g., for a favicon, older browsers)

  • Create fallback meta tags for various browsers (e.g., iOS, WebKit/Chromium forks etc.) describing how a PWA should open

  • Sets the theme color based on the manifest

For Safari, PWACompat also:
  • Sets apple-mobile-web-app-capable (opening without a browser chrome) for display modes standalone, fullscreen, or minimal-ui

  • Creates apple-touch-icon images, adding the manifest background to transparent icons: otherwise, iOS renders transparency as black

  • Creates dynamic splash images, closely matching the splash images generated for Chromium-based browsers

For PWAs on Windows with access to UWP APIs:
  • Sets the title bar color

Keep an eye on the library to see the latest version and features.

Summary

Advanced caching and the add to home screen have been implemented. We are one step closer to the native app counterparts. In the next chapter, we are going to boost Angular performance and work on App Shell to take our application to the next level.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.98.71