Authors: Diego Gonzalez
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.
- This document status: Active
- Expected venue: W3C Web Incubator Community Group
- Current version: this document
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.
-
Enable installation of web apps (cross-origin).
-
Allow the web app to report to the installation origin the outcome of the installation.
-
Enable UAs to supress potential installation-prompt spam.
-
Track campaign IDs for marketing campaigns (with the Acquisition Info API).
- Install same-origin content (see Web Install - same-origin explainer).
- Install arbitrary web content that is not an app (target must have a manifest file and an
id
orstart_url
). Reasons expanded here. - Change the way the UA currently prompts for installation of a web app.
- Associate ratings and reviews with the installed app (see Ratings and Reviews API explainer).
- Process payments for installation of PWAs (see Payment Request API).
- List purchased/installed goods from a store (see Digital Goods API).
- Installing content that does not pass the installability criteria (see installability criteria).
- Define what "installation" means. This is up to each platform and overall we refer to the acquisition of an app onto a device.
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.
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.
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.
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;
}
}
};
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 computedmanifest_id
of the installed app.
- The success value will be an object that contains:
- 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.
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. Aninstall_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.
navigator.install(manifest_id, <install_url> [, <params>])
: The method takes an id and install url and tries to install the web content atinstall_url
. Installation will proceed if the following are true: a. The target web app links to a manifest. b. The target web app's manifest includes either anid
orstart_url
. c. Theid
parameter matches the declared or resolved id of the target web app. 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).
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.
To install a cross domain web site/app, the process is as follows:
- Origin site that triggers the installation must have installation permissions as it tries to install a cross-origin app.
- Target site/app must comply with installability criteria, if any.
- If the target content is not a web app, it can't be installed.
- Prompt the user for install confirmation. User is given a choice about whether to install the target content or not.
- If the users accepts, the content is installed.
- UA default action post-install (generally the app will open/be added to homescreen/start menu/dock).
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.
-
navigator.install
and Permissions API: see integrations with the Permissions API. -
navigator.install
and manifest file'sprefer_related_applications
: When therelated_applications
andprefer_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
andgetInstalledRelatedApps
: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
andside-panel
display-mode: Due to the evolving nature of web apps, there are different surfaces where these can be installed. If the target ofnavigator.install
call has a manifest file with adisplay_override
member that includes aside-panel
value, this can hint to the UA that the app can be installed as a sidebar app if supported.
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.
- 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.
-
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.
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;
}
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.
- 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.
-
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
andgetInstalledRelatedApps
be merged together? See this issue.
- installation origin: the origin that initiates the call to the
install
method. - UA: user agent.
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.