Skip to content
Open
Changes from all commits
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
119 changes: 11 additions & 108 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
User-Initiated PWA Installation
User-Initiated Installation of a Web Application
===============================

A Problem
---------

Web applications can be installed, providing users with a more reliable and integrated experience
alongside other applications they may use on a regular basis. This is generally considered to be
fantastic, providing value to both users and developers.

Today, the process of initiating an installation flow is somewhat fragmented; each user agent has
created a set of entry points, some more discoverable and intuitive than others. The
[Web Install API][api], currently in Origin Trials, aims to create a more consistent developer-facing story, providing an imperative API which allows websites to initiate an installation flow for an arbitrary application,
enabling more seamless and intuitive experiences for users.

However, an imperative API does not provide a strong signal of a user's intent to perform the action, as the only restriction is transient activation. This opens the door for potential abuse or annoyance. See [risks of the imperative API](#risks-of-the-imperative-api).

[api]: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/WebInstall/explainer.md
Today, the process of initiating an installation flow is fragmented; each user agent has
created a set of entry points, some more discoverable and intuitive than others.

The Proposal
----------

We can provide developers with a declarative `<install>` element which renders a button whose content and presentation is controlled by the user agent. Similar to other [permission elements][pepc] (e.g. [`<geolocation>`][geolocation]), the user agent's control over (and therefore _understanding of_) the element's content means that it can make plausible assumptions about a user's contextual intent. Users who click on a button labeled "Install 'Wonderful Application'" are unlikely to be surprised if an installation prompt for exactly that application appears, and they'll be primed to make a good decision about the question such a prompt presents.
A declarative `<install>` element that renders a button whose content and presentation is controlled by the user agent. The user agent's control over (and therefore _understanding of_) the element's content means that it can make plausible assumptions about a user's contextual intent. Users who click on a button labeled "Install 'Wonderful Application'" are unlikely to be surprised if an installation prompt for exactly that application appears, and they'll be primed to make a good decision about the question such a prompt presents.

## The Design - v1, simple button

Expand All @@ -31,21 +21,18 @@ The element will render standardized text and iconography controlled by the user
<img alt='A button whose text reads "Install", with an icon signifying the action of installation.' src='./install-icon.png' width=200>

```html
<install installurl="https://music.youtube.com/"
manifestid="https://music.youtube.com/?source=pwa">
<install>
[Fallback content goes here.]
</install>
```

### Attributes

`installurl` specifies the document to install (this is equivalent to the first parameter of the imperative version). This enables loading the document in the background and obtaining the information needed for the installation dialog. If unspecified, the current document will be installed.

`manifestid` is optional. If _unspecified_, the manifest referenced by the document at `installurl` must have a custom id defined. If specified, it must match the computed id of the site to be installed.
Some events to handle successful install and user aborting the install dialog.

### Behavior

On click, the user agent can display a confirmation prompt with the app's name, origin, and icon for increased security.
On click, the user agent can initial the user agent's existing installation flow.

![An installation prompt for `YouTube Music`.](./dialog-ytmusic.png)

Expand All @@ -66,11 +53,8 @@ If the user agent doesn't support installation, present a simple link:
<img alt='A hyperlink reading "Launch YouTube Music".' src='./install-not-supported.png'>

```html
<install installurl="https://music.youtube.com/"
manifestid="https://music.youtube.com/?source=pwa">
<a href="https://music.youtube.com/" target="_blank">
Launch YouTube Music
</a>
<install>
To install and app, do X and Y in the brower's UI!
</install>
```

Expand All @@ -80,21 +64,6 @@ The element can transform into a simple 'Launch'-style button, a highly requeste

<img alt='A button whose text reads "Launch YouTube Music, from music.youtube.com", with an icon signifying the action of launching.' src='./launch-simple.png' width=200>

## Error handling

The element offers event-driven hooks allowing developers to understand users' interactions, reusing [`InPagePermissionMixin`][mixin] concepts like `promptaction`, `promptdismiss`, and `validationstatuschange` events, `isValid` and `invalidReason` attributes, etc. Additional events will be needed for failures related to manifest fetching/parsing.

Validation errors could include violations of the generally applicable [presentation restrictions][security] for permission elements, as well as data validation errors when processing the referenced manifest.

That said, developers wouldn't actually need to hook into any of those attributes for the simplest
cases: `<install installurl="https://example.com/"></install>` would be sufficient for
straightforward use cases of offering installation.

[pepc]: https://github.com/WICG/PEPC/
[geolocation]: https://github.com/WICG/PEPC/blob/main/geolocation_explainer.md
[mixin]: https://wicg.github.io/PEPC/permission-elements.html#permission-mixin
[security]: https://github.com/WICG/PEPC/blob/main/explainer.md#security-abuse


Please give me some IDL and technical detail!
--------------------------------------------------
Expand All @@ -105,76 +74,10 @@ Ok. Here you go:
[Exposed=Window]
interface HTMLInstallElement : HTMLElement {
[HTMLConstructor] constructor();

[CEReactions, ReflectURL] attribute USVString installurl;
[CEReactions] attribute USVString manifestid;
// events to handle successful install and user aborting the install dialog
};
HTMLInstallElement implements InPagePermissionMixin;
```

The [`InPagePermissionMixin`][mixin] is defined as part of the general Permission
Element proposal, and includes a few attributes and events. We'll reuse those here
for consistency.

* `isValid` will return a boolean: `true` if the element's presentation makes it a valid click
target for users (because the user agent has confidence that it's visible and comprehensible,
and that it's been in that state long enough to be reasonably reliably viewed and comprehended),
`false` otherwise.

* `invalidReason` will return an enum specifying the reason the element is considered invalid,
including invalidity of the element's underlying data (for cases in which the URL is missing
or invalid, or manifest fetching/parsing fails).

* `initialPermissionStatus` and `permissionStatus` will reflect the state of the `install` feature
(which we'll define somewhere as a policy-controlled feature with a default allowlist of
`'self'`).

* `promptaction` events will be fired when the user finishes interacting with any installation
prompt triggered by activating the element.

* Likewise, `promptdismiss` will be fired when users cancel or dismiss the installation prompt.

* `validationstatuschange` events fire when the validation status changes (crazy, right?).

The element's [activation behavior][activation behavior] is quite similar to other permission
elements (e.g. [`<geolocation>`'s activation behavior][activate-geo]): we'll check to see whether
the event is trustworthy, the element is valid, permission to `install` is available and so on.
Then we'll trigger an installation prompt in an implementation defined way. This will result in
the user making some decision, leading to either a `promptdismiss` or `promptaction` event firing
on the element.

The element hooks directly into the backend of navigator.install. When clicked, it will
load the `installurl` in the background to obtain the web application manifest and related
resources needed for the installation dialog. The steps here will be similar to those defined
for [the "manifest" link type][manifest-fetch], fetching and processing the manifest according
to its [processing steps][manifest-process]. If we get a valid manifest back, the installation
dialog is presented. If not, an error event is fired and the `<install>` element reports the
error appropriately.

[activation behavior]: https://dom.spec.whatwg.org/#eventtarget-activation-behavior
[activate-geo]: https://wicg.github.io/PEPC/permission-elements.html#ref-for-dom-inpagepermissionmixin-features-slot%E2%91%A1%E2%93%AA
[manifest-fetch]: https://html.spec.whatwg.org/multipage/links.html#link-type-manifest:linked-resource-fetch-setup-steps
[manifest-process]: https://html.spec.whatwg.org/multipage/links.html#link-type-manifest:process-the-linked-resource

## Future Work

The following features are planned for future iterations:

### Custom Information in Button

Rendering the app name, origin, or icon in the install element would provide an even stronger signal of user intent, but also introduces a variety of complications, such as:
- **Performance:** When and how to get the information to show in the button
- **UX:** Whether to use a two-tap flow (tap 1 loads info, tap 2 installs)
- **Security:** Long app names. See [handling very long app names](#what-if-this-is-an-app-for-a-donaudampfschifffahrtsgesellschaftskapitän). Is the secondary installation confirmation prompt necessary?
- **Styling/Accessibility:** App icon contrast ratios. Button layout/width.

We believe it's worth it to solve these problems, but don't think it should delay gathering initial feedback.

### Potential Additional Attributes

- `manifesturl`: Link to the manifest file
- `includeicon`: If specified, fetches and renders the app's icon (in addition to the install icon)

Open Questions
--------------

Expand Down Expand Up @@ -233,7 +136,7 @@ User agents will need to consider how to handle very long words, including appro

Alternatives
------------

* The Install API
* Given that the behavior discussed above would support both installation and launching, depending
on the application's installed state, some more generic name might be appropriate. `<pwa>` or
`<webapp>` could more broadly describe a potential range of behavior. I prefer `<install>`, as
Expand Down