Linda Ikechukwu Frontend developer. Writer. Community Strategist. Building web interfaces that connect products to their target users.

Project Fugu: 5 new APIs to try out in your PWA

7 min read 2136

Project Fugu: 5 new APIs to try out in your PWA

The web platform has remained attractive to both software developers, product owners, and stakeholders alike because of its reach and universal access. Powerful web apps work everywhere regardless of device type or operating system. Now, when combined with the PWA sauce, web apps get the added benefits of offline access, alongside other capabilities that were previously only possible on native platforms.

Despite the fact that PWAs have come a long way since they were popularized by Google in 2015, there’s still a long way to go. In order to continually bridge the gap between what’s possible on the web versus on native, Google, Microsoft, Intel, and some other corporations came together to initiate, “The Web Capabilities Project” or what is commonly known as Project Fugu, with one goal:

Web apps should be able to do anything native apps can

In this article, we’ll learn about five new APIs that have recently been shipped from Project Fugu to help developers build full-featured apps on the web.

Contact API

The Contact API gives you access to a user’s contact list, (with their permission, of course) the way native apps do. For example, let’s assume you’re building a web app that helps people come up with random thoughtful messages for their friends.

Previously if you want to send a message generated in a web application to a member of your contact list, you would have to copy the message, switch screens to go to your phone contact, select the target contact, tap to send a message, paste the text, then send. With the new Contact API, you can now add the option to let users automatically select a contact from their contact list to send the generated message to, as opposed to having to manually copy it, look for the receiving contact, paste, and then send.

With the Contact API, there is no need to switch screens. App developers can add the option to select the contact right from their application. You won’t have to copy and paste and you won’t have to switch apps.

Screen Showing Shared Contacts To Select

A few things you should know about this API:

  • It can only be accessed via secure context (i.e., https) or localhost for testing
  • It is available on Chrome 80 and upwards
  • It only currently works on Android and requires at least Android M (6.0.1)
  • It was built with security in mind to ensure that the browser will only share what the user has chosen to
  • It can only be triggered via a gesture like a click or tap, to ensure that websites cannot randomly show the picker without any context
  • There is no bulk select or select all option

To get started with the Contact API:

const sendMessage = async() => {
  const isSupported = ('contacts' in navigator && 'ContactsManager' in window);
  const availableProperties = await navigator.contacts.getProperties();
  if(isSupported && availableProperties.includes('tel')){
    try{
      const props = ['name','tel',];
      const opts = {multiple: true};
      const contacts = await navigator.contacts.select(props, opts);
      functionToSendMessageToSelectedContacts(contacts);
    }catch{
      //handle any errors
    }
  }else{
    alert('Contacts API not supported in this browser, please copy and paste message instead')
  }
}

The navigator.contacts.getProperties method returns a promise that resolves to an array of strings containing contact properties supported by a particular browser, like (name, email,tel, address,icon). navigator.contacts.select does two things — when called, it returns a promise and displays the contact picker to allow the user to select the contact(s) they want to share with the site. After selecting the contacts to share and clicking Done, the promise resolves with an array of contacts selected by the user. It accepts two arguments — an array of properties that should be returned for each contact and a multiple indicator to specify whether multiple contacts can be selected or not.

We made a custom demo for .
No really. Click here to check it out.

To see the Contact API in action, check out this demo app.

Web Share Target API

The first release of the Web Share API, which was launched in Chrome 61 for Android, allows websites to share textual data to any supported destination selected by the user, using their device’s native sharing capabilities. This is made possible via the navigator.share() method, which takes in an object that contains either a url and/or text property with an optional title property:

shareButton.addEventListener("click", async () => {
  if(navigator.share){
    try {
        await navigator.share({
          title: "5 Developer NewsLetters to help you grow as a frontend developer ",
          url: "https://www.codewithlinda.com/blog/developer-newsletters-to-help-you-grow/",
          text:"Discover 5 new newsletters that will help you grow in your career"
});
       console.log("Data was shared successfully");
    }catch (err) {
       console.error("Share failed:", err.message);
    }
    }else{
      console.log("Share not supported")
   }
});

Like every other sensitive API, the share method can only be triggered via a gesture to prevent abuse. When a user clicks the share button, the navigator.share() method is called, it triggers the user’s device share target picker to pop up and then returns a promise that resolves when the user selects an application to share to.

Share Target Picker For My Android Device

After a while, an addition was made to the Web Share API to allow the sharing of files alongside the text, via an added files property that accepts an array of files to be shared. This addition was tagged as the Web Share API Level 2 and was shipped to Chrome 75 and upwards on Android:

if (navigator.canShare && navigator.canShare({ files: [...files] })) {
  try{
      await navigator.share({
         files: [...files],
         title: 'Pictures',
         text: 'Our Pictures.',
      })
     console.log('Share was successful.')
   }catch(error){
     console.log('Sharing failed', error)
   }
} else {
  console.log(`Your system doesn't support sharing files.`);
}

The navigator.canShare() method checks if the intended files can be shared by the browser.

At the time of writing this article, Chrome does not support sharing of PDF files (see permitted file type extensions for Chrome).

Note that files passed to the files property should be in the form of JavaScript File objects, like what is retrieved from <input type='file'>.

Here’s a demo of the Web Share API Level 1 and 2 in action. Also, see the current browser support table here.

That’s not all, to take web sharing up a notch, the Web Target API Level 1 and 2 were released on Chrome 71 and Chrome 75 on Android. The Web Target Share API allows installed PWAs to be on the receiving end of sharing. Now, instead of only being able to provide content to be shared, installed PWAs can also receive shared content.

To do this, you first need to register your app as a share target within your manifest file:

//In manifest.json
{
  "share_target": {
    "action": "share.html",
    "params": {
      "title": "name",
      "text": "description",
      "url": "link"
    }
  }
}

The action property specifies the URL to handle the shared content within your PWA. How you decide to handle incoming shared data is really up to you and what your app does.

To see the Web Share Target API in action, check out this demo app. For browser support, the Web Share Target API is (at the time of writing this article) supported by Chrome and Edge 76 or later on Android and Chrome 89 or later on Chrome OS.

App Shortcuts API

If you long press an application icon on your mobile device, a list of shortcuts will pop up. For example, if you long press the Instagram launcher icon on your device, a panel that lists Camera, New Post, Activity, and Chats will pop up.

Shortcuts menu for instagram on my Android device

This is exactly what the App Shortcuts API, released in Chrome 84 for Android and Chrome 85 for Windows, does for PWAs. Developers can now provide quick access to common actions that users frequently perform within their application. The presence of app shortcuts has been suggested to enhance users’ productivity as well as increase their levels of engagement with the web app.

To add app shortcuts to your PWA, add a shortcuts entry to your manifest file. For example, if you’re building a stock investment web app, your shortcuts could include “Buy Shares”, “Sell Shares” and “Deposit Funds”:

//in manifest.json
"shortcuts": [    
    {  
      "name": "Buy Shares",  
      "url": "/buy-shares?utm_source=homescreen",     
    },
    {  
      "name": "Sell Shares",  
      "url": "/sell-shares?utm_source=homescreen",     
    },  
    {  
      "name": "Deposit Funds",  
      "url": "/deposit-funds?utm_source=homescreen",     
    },     
]

The shortcuts manifest entry is an array of objects containing information for individual shortcuts. Each shortcut object should have a name and url property with or without optional short-name, description, and icon properties.

A few things you should know about this API:

  • It only works for PWAs that have been installed on the user’s device
  • The app shortcut menu is triggered via platform specific gestures. For Android long press the app, for Windows right-click on the app’s icon on the taskbar

Use this link to view current browser support. To see the app shortcuts in action, see this demo app.

Badging API

You’ve probably seen those numbers displayed in the top right of app icons on your phone or desktop, indicating how many unread messages, notifications, or updates exist within the app. These usually serve as visual cues to get users to open the app and see what’s waiting, which increases engagement. The good news is, with the new Badging API, you can now add the same functionality to your PWAs.

Example of Twitter with eight notifications and another app showing a flag type badge

The Badging API provides two methods — navigator.setAppBadge and navigator.clearAppBadge. The navigator.setAppBadge(value) method sets the value of the badge to the value of the value argument passed to it, while the navigator.clearAppBadge() removes the app’s badge:

if( "setAppBadge" in navigator && "clearAppBadge" in navigator){
   try{
      await navigator.setAppBadge(badgeCount)
   }catch(error){
      //handle errors here
   }
}

How you decide to implement badging for your PWA really depends on you and what you want to achieve with your app.

At the time of writing this, the Badging API does not work on mobile, but it currently works on Windows and macOS, in Chrome 81, and on Edge 84 or later. See the current browser support table here.

To see the Badging API in action, visit this demo app.

Screen Wake Lock API

Depending on the user-defined settings of a device, a device is likely to go to sleep after a few minutes of being idle or not receiving any user gestures like a click or touch. This behavior can get frustrating, especially when you’re using virtual experience apps that require you to just watch or observe without any interactions. You’ll have to either tap or touch the screen at intervals to prevent the screen from dimming and eventually going off. Examples of such apps are a virtual tour app, a presentation app, or a follow-along recipe app.

The ability to prevent screens from going to sleep has only been available to native applications. Prior to the Screen Wake Lock API, web developers had to resort to hacky, security prone, and power-hungry workarounds to achieve this behavior.

To activate a screen lock:

let wakelock = null;
const requestWakeLock = async () => {
  if ('wakeLock' in navigator) {
      try {
        wakeLock = await navigator.wakeLock.request();
      catch (err) {
        console.error(`${err.name}, ${err.message}`);
    }
  }
}

Unlike previous APIs, this API does not require user gestures to be activated. The navigator.wakeLock.request() method is used to request a screen wake lock. It returns a promise which resolves to a WakeLockSentinel object if the request was successful. The wakelock variable is used to hold a reference to the WakeLockSentinel object, as you may need to access some of its methods and properties later.

To preserve battery life, it is advised to release the screen lock after it has fulfilled its purpose. For example, in the case of the virtual tour app, the screen lock should be released at the end of the tour. This can be done using the release method of the WakeLockSentinel object:

wakeLock.release();
wakeLock = null;

Release the screen lock and also release the reference to the existing WakeLockSentinel object by setting wakeLock variable back to null.

According to the Screen Wake Lock API lifecycle, when a page or window with an active screen lock is minimized or switched from, the screen wake lock will automatically be released. To reacquire the screen wake lock, listen for the visibilitychange event:

const handleVisibilityChange = async () => {
    if (wakeLock !== null && document.visibilityState === 'visible') {
        await requestWakeLock();
    }
};

document.addEventListener('visibilitychange', handleVisibilityChange);

First, check if there is an existing WakeLockSentinel object reference and if the page is visible to ensure that we only reacquire screen wake lock when the target page or window becomes active again.

To see what the WakeLockSentinel object looks like, you can run await navigator.wakeLock.request() on your browser’s console.

To see the Screen Wake Lock API in action, check out this demo web app. See the current browser support table here.

Conclusion

In this article, you’ve been introduced to five exciting APIs that will help you build better featured PWAs. Now, go build something great!

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Linda Ikechukwu Frontend developer. Writer. Community Strategist. Building web interfaces that connect products to their target users.

Leave a Reply