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 Applications Working Group
- Current version: this document
Modern browsers have UX that enable users to install web content on their devices. This content ranges from web sites to Progressive Web Apps, and different UAs implement mechanisms and UI affordances that a user can trigger or the UA can signal for this installation to happen.
The Web Install API aims to standardize the way installations are invoked by developers, creating an ergonomic, simple and consistent way to get web content installed onto a device. It allows a web site to install web content (both from the same or cross origin). This capability can be used by a site to install itself when some installability criteria is met, which can vary with different UAs.
- Enable installation of web apps (same-origin).
- Complement
beforeinstallprompt
for platforms that do not prompt for installation of web content. - Allow the web app to report to the installation origin the outcome of the installation.
- Enable UAs to supress potential installation-prompt spam.
- Install cross-origin content (see Web Install - cross-origin explainer).
- Change the way the UA currently prompts for installation of a web app.
- Replace
beforeinstallprompt
or associated behaviour. - 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).
- Enumerate if the app/related apps are installed (see getInstalledRelatedApps).
The site can trigger its own installation.
The current way of supporting installation is via the onbeforeinstallprompt
event, which only works in browsers that have a prompting UI affordance.
The navigator.install
method allows a imperative way to install web content, and works for UAs that prompt and don't prompt:
/* tries to install the current document */
const installApp = async () => {
if (!navigator.install) return; // api not supported
try {
await navigator.install();
} catch(err) {
switch(err.name){
case 'AbortError':
/* Operation was aborted*/
break;
}
}
};
The navigator.install
method can overlap with some functionality of beforeinstallprompt
for same-origin installation. When the method is called it will trigger the UA to prompt for the installation of an application. This is analogous to when the end user clicks on an affordance that the UA might have to inform the user of installing. On Edge, Chrome (desktop) and Samsung Internet (mobile), this would be when the user clicks on the 'app available' banner or related UX that appears on the omnibox of the browser. For browsers that do not implement prompting, the expected behaviour is analogous to their installation paradigm. For example, in Safari (desktop) the behaviour might be that it shows a dialog to add the content to the dock as an app.
On UAs that support prompting, the threshold for navigator.install
to resolve on same-origin installations uses the same checks that onbeforeinstallprompt
currently has for prompting (if required by the UA). The promise doesn't resolve unless the installability criteria is met. Note that the criteria defined by UAs varies and can be that there is NO criteria aside from requiring an id in the site's manifest.
When called on the same domain, the install
method will trigger/open the prompt for installation the same way that using onbeforeinstallprompt
does right now for browser that prompts. If there is an error with the installation, then the promise returns a DOMException
of type 'AbortError'.
To install a web site/app, the site/app would use the promise-based method navigator.install(id, install_url, [<params>])
. This method will:
- Resolve when an installation was completed.
- The success value will be an object that contains:
- Computed
id
: computedid
of the installed web content. This is theid
that is passed on as a parameter to reference the installed content.
- Computed
- 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 was not completed.
/* simple example of using navigator.install */
const installApp = async () => {
try{
const value = await navigator.install();
}
catch(err){console.error(err.message)}
};
The same-origin part of the Web Install API consists of the extension to the navigator interface with the install method. The install method can be used in several different ways. There is no difference in behaviour when this is called from a standalone window or a tab.
navigator.install(<params>)
: The method takes no parameters and tries to install the current document. Installation will proceed as long as the current document links to a manifest that includes a declared id.navigator.install(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.
Both calls can also receive an object with parameters that they can use to customize a same domain installation. These parameters alter how the app is installed and are defined in an object. More information about the parameters is found in the Parameters subsection of this specification.
The navigator.install
call can receive an object with a set of parameters that specify different installation behaviours for the app.
- referral-info: this parameter takes the form of an object that can have arbitrary information desired to be captured at the time of installation.
To install a same domain web site/app, the process is as follows:
- Site/app must comply with installability criteria, if any.
- 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).
-
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 preferred catalog. If this is not possible then it fallback to a default UA install. -
navigator.install
and getInstalledRelatedApps(): If a web app tries to install itself (same domain install) it can first use thegetInstalledRelatedApps()
to check if it is already installed and hide the installation UI.
const relatedApps = await navigator.getInstalledRelatedApps();
relatedApps.forEach((app) => {
if(app.platform === 'webapp') {
/* hides install button that calls `navigator.install method` */
}
});
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 same-origin version of the API is that it allows to install any content, as long as it is initiated with a user action. Note that even though there are no installability requirements, the navigator.install
method does require an id to install any content.
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.
-
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 content using the Web Install API requires a user activation.
For same-domain installs, the user gesture and the final installation confirmation (current default behaviour in the browser before installing an app) work together to minimize the risk of origins spamming the user for unrequested installations.
- 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. An event could be fired if the prompt/installation is successful and provide similar information to the one that the promise returns. Once the API ships this can be a fast follow-up to enable installs in a declarative way.
-
Should we enable a try-before-you-buy flow scenario for web install?
-
Should we allow an
AbortController
to enable cancelling the installation if the process takes too long?
- Installation origin: The origin that initiates the call to the
install
method. - Installed origin: The origin that is installed with the
install
method. - Declared manifest id: The id as it is declared in the manifest. See MDN documentation for more info.
- Resolved manifest id: The processed id after it is resolved against the
start_url
's origin. Since the declared id is resolved against an origin, this will take the form of a url (e.g. "https://example.com/my_app"), although it may not point to a valid resource. See W3 manifest spec for detailed parsing info.
This explainer takes on the work previously published by PEConn.
Special thanks to Amanda Baker, Marcos Cáceres, Alex Russell and Howard Wolosky.