Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require id in manifest and support 0 param installation #894

Merged
merged 5 commits into from
Nov 19, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions WebInstall/explainer_same_domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ The current way of supporting installation is vai the `onbeforeinstallprompt` ev
The `navigator.install` method allows a imperative way to install web content, and works for UAs that prompt and don't prompt:

```javascript
/* tries to install the current domain */
amandabaker marked this conversation as resolved.
Show resolved Hide resolved
/* tries to install the current document */
const installApp = async () => {
if (!navigator.install) return; // api not supported
try {
await navigator.install('content_id_123');
await navigator.install();
} catch(err) {
switch(err.name){
case 'AbortError':
Expand All @@ -61,7 +61,7 @@ const installApp = async () => {

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*.
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'.

amandabaker marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -72,7 +72,7 @@ When called on the same domain, the **`install` method will trigger/open the pro

### The `navigator.install` method

To install a web site/app, the site/app would use the promise-based method`navigator.install(<id>[[, install_url], <params>])`. This method will:
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:
diekus marked this conversation as resolved.
Show resolved Hide resolved
diekus marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -85,7 +85,7 @@ To install a web site/app, the site/app would use the promise-based method`navig

const installApp = async () => {
try{
const value = await navigator.install('content_id_123');
const value = await navigator.install();
}
catch(err){console.error(err.message)}
};
Expand All @@ -96,8 +96,10 @@ const installApp = async () => {
#### **Signatures of the `install` method (same-origin)**
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.

1. `navigator.install(id[[, install_url], <params>])`: The method takes an id (and optional install url) and tries to install the current origin. If the content being installed has a manifest file, this `id` must match the value in the manifest file. If there is no manifest file present, this `id` will act as the app id for the installed content. This is relevant since if the installed content were to be given a manifest file and made into an application, there is a way to automatically update the app going forward.
The call can also receive an object with parameters that it 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](#parameters) subsection of this specification.
1. `navigator.install()`: The method takes no parameters and tries to install the current document. If the content to be installed does not link to a manifest with a valid id, then installation will fail.
amandabaker marked this conversation as resolved.
Show resolved Hide resolved
2. `navigator.install(id, install_url, [<params>])`: The method takes an id and install url and tries to install the web content at `install_url`. If the content to be installed does not have a linked manifest that specifies an id, and the provided `id` parameter does not match the computed id, then installation will fail.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, to be clear, the API is now enforcing same-origin users to have a id defined in the manifest file, regardless of whether they're using the 0-param or the 2-param version. I generally feel ok with that, given that a dev adding same-origin usage of navigator.install on a site should also be able to update the manifest file.

That being said, if we're requiring a id to be explicitly defined in the manifest now for same-origin, does it make sense to have an id param at all? Should it just be a "one-param" method that takes the install_url and optional install params? It's not clear to me what the value/scenario is. Would a dev at /foo/ that is trying to install the app on /bar/ care about the id? Wouldn't they just care about installing "that app" that's at /bar/ and not "that app but only if its id hasn't changed since I last wrote this code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not every web app will have an install_url? I think having the 0 param makes sense to just install content that already is defined as an "app" with an id, and the 2 params is for when the developer wants to have a fine control of how to install content? (ie, custom install_url, matching ids and additional parameters.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are actually two different install_url's in play here:

  1. The install_url that is (optionally) defined in the manifest.
  2. The install_url that is the (required?) second parameter in the 2-param signature.

There's no requirement for the manifest to have an install_url. and even if it does, there's no requirement that the install_url used in the API matches the one that is optionally specified in the manifest. The install_url in the API signature simply tells the UA where to go to find the manifest.

This mostly comes down to whether we are allowing the installation of web apps that don't have a manifest that at least specifies an app id. If an app id is going to be required to be specified in the web manifest for the API to be able to install it, then I don't see a compelling argument for specifying the app id in the API signature at all (at least there isn't a well documented one in the explainer so far). If we are allowing the API to install web apps that don't have an id specified in the manifest, then I think we should clearly document in the explainer with a table the full set of scenarios where an id is and isn't expected in the manifest.


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](#parameters) subsection of this specification.
amandabaker marked this conversation as resolved.
Show resolved Hide resolved

#### **Parameters**

Expand Down