Skip to content

Latest commit

 

History

History
225 lines (148 loc) · 19.3 KB

explainer_cross_domain.md

File metadata and controls

225 lines (148 loc) · 19.3 KB

Web Install API (Cross-Origin)

Authors: Diego Gonzalez

Status of this Document

This document is a starting point for engaging the community and standards bodies in developing collaborative solutions fit for standardization. As the solutions to problems described in this document progress along the standards-track, we will retain this document as an archive and use this section to keep the community up-to-date with the most current standards venue and content location of future work and discussions.

Introduction

As Web applications are becoming more ubiquitous, there are growing needs to aid discovery and distribution of said applications. The Web Install API provides a way to democratise and decentralise web application acquisition, by enabling "do-it-yourself" developers to have control over the application discovery and distribution process, providing them with the tools they need to allow a web site to install a web app.

The acquisition of an web app can originate via multiple user flows that generally involve search, navigation, and ultimately trust that the UA will prompt or provide some sort of UX that support "installing/adding" the desired app. There are multiple use cases for this feature, as seen in the use case section, but the core concept is the installation of a web app directly from a web page.

The current alternative to the Web Install API implies the user needs to rely on search engines, app stores, proprietary protocols, proprietary "smart" banners, UA prompts, hidden UX and other means that take the user out of their navigating context. They also represent additional steps towards the acquisition of the app.

Inherently, these alternative user flows to "install" an app rely on multi-step processes that at best require a couple of clicks to navigate to an origin and install it, and at worst involve the user searching on browser menus for a way to add the app to their device. The web platform is not capable of providing a seamless, consistent experience that allows users to discover and acquire applications in a frictionless manner. Every additional step in the acquisition funnel for web apps comes with an additional drop off rate as well.

Moreover, the Web Install API feature is beneficial for app discovery: it allows developers to create their own acquisition mechanism and tailor it to benefit users that:

  • might not know that a web app exists for the current origin.
  • don't understand what the icon/prompt in the omnibox does.
  • don't know how to deep search several layers of browser UX to add the app to their devices.
  • don't use app stores to discover new app experiences.

Goals

Non-goals

Use Cases

The Web Install API enables installation of cross-origin web applications. A website will be able to include a button to install an application, which can be hosted in another domain. These are some examples of use cases enabled by the new API.

Websites installing their web apps

Picture a user browsing on their favorite video streaming web app. The user might browse to this web app daily, yet not be aware that there is a way that they can install the app directly from the app's UI. This could be through a button that the webapp would be able to implement, that would trigger the installation.

The website can also provide a way to directly acquire other applications it might offer, like a dedicated "kids" version of the app, or a "sports" version of the app. The developer is in control and can effectively advertise and control their applications, which having to redirect users to platform-specific propriatery repositories, which is what happens now.

SERP app install

Developers of Search Engines could use the API to include a way to directly install an origin that is an application. A new feature could be offered by search engines that could see them offering a frictionless way to acquire an app that a user is searching for. This could also aid discovery as a user might not be aware that a specific origin has an associated web application they could acquire.

Creation of online catalogs

Another potential use case for the API is related to the creation of online catalogs. A web site/app can list and install web apps. A unique aspect of this approach is that since the applications that are installed are web apps, this could enable a new set of true cross-device, cross-platform app repositories.

/* tries to install a cross-origin web app */

const installApp = async (manifest_id, install_url) => {
    if ('install' in navigator === false) return; // api not supported
    try {
        await navigator.install(manifest_id, install_url);
    } catch(err) {
        switch(err.name){
            case 'AbortError':
                /* Operation was aborted*/
                break;

        }
    }
};

Install flow from an app repository

Proposed Solution

The navigator.install method

To install a web app, a web site would use the promise-based method navigator.install(<manifest_id>[, <install_url>[, <params>]]);. This method will:

  • Resolve when an installation was completed.
    • The success value will be an object that contains:
      • manifest_id: string with the computed manifest_id of the installed app.
  • Be rejected if the prompt is not shown or if the app installation did not complete. It'll reject with a DOMException value of:
    • AbortError: The installation (prompt) was closed/cancelled.

Promises resolve/reject flow

Signatures of the install method (cross-origin)

The cross-origin part of the Web Install API consists of the extension to the navigator interface with an install method. This method receives:

  • manifest_id: declares the specific application to be installed. This is the unique id of the application that will be installed. This value must match the id specified in the manifest file.
  • install_url: a url meant for installing an app. This url can be any url in scope of the manifest file that links to it. An install_url must not redirect nor contain extra content that is not relevant for installation purposes.
  • optional parameters.

If the manifest_id is the what to install, the install_url is the where to find it.

Unless the UA decides to gate this functionality behind installation, the behaviour between calling the install method on a tab or on an installed application should not differ. The install method can be used in two different ways.

  1. navigator.install(manifest_id, <install_url> [, <params>]): This signature of the method requires the id of the application to be installed (manifest_id), and the installation location for the app (install_url). This is the most common API use case the API for cross-origin scenarios.

This will prompt for installation of the app if the requesting origin has installation permissions (see security section) and the target application has specified this domain in its install_sources manifest field.

Parameters

The navigator.install call can receive an object with a set of parameters that specify different installation behaviours for the app. It is also a way to future-proof the API if additional data were required with the call.

  • referral-info: this parameter takes the form of an object that can have arbitrary information required by the calling installation domain. This information can later be retrieved inside the installed application via the Acquisition Info API.

Installing the web app

To install a cross domain web site/app, the process is as follows:

  1. Origin site that triggers the installation must have installation permissions as it tries to install a cross-origin app.
  2. Target site/app must comply with installability criteria, if any.
  3. If the target content is not a web app, it can't be installed.
  4. Prompt the user for install confirmation. User is given a choice about whether to install the target content or not.
  5. If the users accepts, the content is installed.
  6. UA default action post-install (generally the app will open/be added to homescreen/start menu/dock).

The navigator.getInstalledApps method

If supported by the UA, the getInstalledApps method returns a list of the content that has been installed from that installation origin which is still installed on the device at the time of execution. This is an async method of the navigator interface that allows the installation origin to know which applications it has installed.

This works until cache is cleared. The installation origin will not be informed of any apps installed by other means, whether via another installation origin, directly through the browser, or by a native app store. The method returns a list of manifest ids of content installed from the calling origin.

Additionally, if the browser has an active 'Do Not Track (DNT)', equivalent 'Global Privacy Control (GPC)' setting, is in Private browsing mode, or is an opinionated browser towards privacy, this is ignored and installation origins will not be allowed to know if that application is installed. In this case the navigator.getInstalledApps will return a null.

  • The approach for showing which apps have been installed from this origin follows the same API approach where the information is accessible if it matches a partition key, instead of just the link URL. This ensures installed apps can be seen only from the origin matching all parts of the key.

Relation with other web APIs/features

  • navigator.install and Permissions API: see integrations with the Permissions API.

  • navigator.install and manifest file's prefer_related_applications: When the related_applications and prefer_related_applications key/values are present in the manifest, the UA should try to handoff the install to the prefered catalog. If this is not possible then it fallback to a default UA install.

  • navigator.getInstalledApps and getInstalledRelatedApps: getInstalledApps is called from an origin and can list applications that are installed on the device originating from the current site. getInstalledRelatedApps on the other hand is called from a web app and returns which alternate versions of an app (platform specific versions for example) are already installed on the device.

    • getInstalledApps can be used to change install UX in online stores if an app is already installed (changing the text on a button from "Install" to "Open" for example).
    • getInstalledRelatedApps can be used to "mute" notifications or hide install UI for a web application if an alternate version of the app is already installed (avoid duplicate notifications if a user has a web version and a platform-specific version of the same app for exmaple).
  • navigator.install and side-panel display-mode: Due to the evolving nature of web apps, there are different surfaces where these can be installed. If the target of navigator.install call has a manifest file with a display_override member that includes a side-panel value, this can hint to the UA that the app can be installed as a sidebar app if supported.

Installability criteria

In order for an application/site to be installed, it must comply with installability criteria. This criteria is entirely up to the UA, can vary depending on the installation target, and can be optional.

Modern browsers allow for different degrees of installation of different types of content, ranging from traditional web sites all the way up to Progressive Web Apps. The core functionality of the API is that it allows to install anything initiated with a user action.

A user agent might decide to have only the requirement of HTTPS to allow installation of a web site, or may need as well a manifest file and/or service worker to install a web app or might not require anything at all, allowing the user to install any content they wish.

Privacy and Security Considerations

Same-origin policy

  • The content installed using the navigator.install does not inherit or auto-grant permissions from the installation origin. This API does not break the *same-origin security model of the web. Every different domain has its own set of independent permissions bound to their specific origin.

Preventing installation prompt spamming from third parties

  • This API can only be invoked in a top-level navigable and be invoked from a secure context.

  • The biggest risk for the API is installation spamming. To minimize this behaviour, installing a PWA using the Web Install API requires a user activation.

  • A new permission type will be introduced for an origin, that would allow it to install web apps. The first time a website requests to install an app (use the API) the UA will prompt the user to confirm that the website can install other apps into the device. This prompt is similar to that of other permissions like geolocation or camera/microphone. The UA can decide how to implement this prompt.

A website that wants to install apps will require this new permission and will only be able to prompt the user for this in a period of time defined by the implementer. This will avoid spam from websites constantly asking for a permission to install apps, and will force websites to only prompt when there is a meaningful user intent to install apps.

The installation permission for an origin should be time-limited and expire after a period of time defined by the UA. After the permission expires the UA will prompt again for permission from the user.

Integration with the Permissions API

A new permission that can be associated with an origin means a new integration with the Permissions API. The install API will make available the "installation" PermissionDescriptor as a new powerful feature. This would make it possible to know programmatically if install would be blocked.

/* example of querying for the state of an installation permission using the Permission API  */

const { state } = await navigator.permissions.query({
  name: "installation"
});
switch (state) {
  case "granted":
    navigator.install('https://elk.zone');
    break;
  case "prompt":
    //shows the install button in the web UI
    showInstallButton();
    break;
  case "denied":
    redirectToAppStore();
    break;
}

Gating capability behind installation

A UA may choose to gate the navigator.install capability behind a requirement that the installation origin itself is installed. This would serve as an additional trust signal from the user towards enabling the functionality.

For cross-origin installs, the user gesture, the new origin permission, the new manifest field the final installation confirmation (current default behaviour in the browser before installing an app) and the optional gated capability work together to minimize the risk of origins spamming the user for unrequested installations, give developers complete flexibility about where their apps will be installed from and provide the user with an implicit (double: one for the user gesture, the other one from the prompt before installing) confirmation before the app gets installed on their device.

Alternative Solutions

  • HTML anchor tag target install <a href="https://airhorner.com" target="_install">honk</a>: An alternate solution to allow installation of web apps is by allowing a new target type of _install to the HTML anchor tag. This has the benefit of being able to work in environments that have JS disabled and can also be another entry point for installation. While this is an elegant solution, it limits the amount of information a developer can act upon that the promise does provide, such as if the prompt was shown or if the origin has permissions to install apps.

Open Questions

  • Should we allow an AbortController to enable cancelling the installation if the process takes too long?

  • Can we remove power from the developer to query if the app is installed by offloading to the UA the knowledge of which apps are installed?

    • Is there any form of attribute that can be added to a DOM element to signal this distinction/difference?
  • Should getInstalledApps and getInstalledRelatedApps be merged together? See this issue.

Glossary

  • installation origin: the origin that initiates the call to the install method.
  • UA: user agent.

Acknowledgements

This explainer takes on the work previously published by PEConn.

Special thanks to Amanda Baker, Patrick Brosset, Alex Russell, Howard Wolosky, Lu Huang, Jonathan Kingston and the PWA Builder team for their input.