w3ctag / design-reviews

W3C specs and API reviews
Creative Commons Zero v1.0 Universal
328 stars 55 forks source link

Web Install API - Cross-Origin #946

Open plinss opened 5 months ago

plinss commented 5 months ago

Hola TAG! I'm requesting an early TAG review of the Web Install API.

The Web Install API allows a web site to install a web app (cross domain). This functionality allows the creation of web based catalogues that can install PWAs directly from the web and into multiple platforms.

Further details:

You should also know that...

there's plenty of positive developer feedback for an API like this one!

LeaVerou commented 5 months ago

@plinss, @hober and I looked at this today during a breakout. We didn't quite understand how the flow is supposed to work for the app store use case. How would the app store get manifest ids, given that it seems the only way to procure a manifest id is after installation? Why not simply provide URLs to manifest files? What does the additional complexity of a manifest id get us?

Also, the install_sources field seems to largely be replicating CORS functionality. Obviously, installing is a markedly different use case than reading, so there needs to be some way to declare the author intent that not every website that can read the manifest should be able to install the app, but an Access-Control-Allow-* header seems like a more natural fit for this.

hober commented 3 months ago

@diekus, did you see @LeaVerou's questions above?

diekus commented 3 months ago

Hola @hober @plinss and @LeaVerou,

Thanks for your patience! In the app store use case, the developer must already have this information. Could be asked when an app is being submitted or previous information that someone wanting to link and install 3P apps can easily find out. For cross-origin installs, the installing origin needs to have the to-be-installed origin's manifest id beforehand. Part of the reason we prefer to have an id for the app instead of pointing to the manifest's URL is because this URL can change. The id does not point to a resource that can be navigated to. It is just a unique way to identify the application.

About CORS I think this is good feedback! I'd like to keep CORS functionality implementation open to a future/parallel expansion of Web Install for sure. To start though, CORS is a bit less developer friendly, and thinking about developer ergonomics I'd like to have the install origins definition not rely (only) on headers.

If both CORS and manifest install_sources were to be supported in the future, do you see this as an acceptable solution?

cc @amandabaker @dmurph

hober commented 3 months ago

@diekus wrote:

For cross-origin installs, the installing origin needs to have the to-be-installed origin's manifest id beforehand.

Why? Having a manifest at all isn't required for the same-origin installation case, so why require it in the cross-origin one?

hober commented 3 months ago

@diekus wrote:

For cross-origin installs, the installing origin needs to have the to-be-installed origin's manifest id beforehand.

Why? Having a manifest at all isn't required for the same-origin installation case, so why require it in the cross-origin one?

Put another way: if any website can provide a button for the user to add it to the Home Screen or Dock, and if it's reasonable for some other website to be able to initiate that on the original site's behalf (a premise I'm not personally sold on but let's grant it for the sake of this conversation), why would we limit the second scenario to a(n inscrutable to the user) subset of websites?

diekus commented 2 months ago

Hola @hober, thanks for your feedback, we've been pondering about the implications of navigator.install for same/cross-origin installations and the requirement of an id. I've reviewed the current designs for the API and think some changes are needed to warrant consistency between the same/cross origin use case (this is a very valid point you bring up!) and futureproofing the API.

First, we want to make both use cases require an id. This doesn't have to be a manifest id, it could be any string that the developer uses to identify or refer to the content. If this is a cross-origin scenario for a web app, then highly likely this will be a manifest id. In a same-origin scenario, where there might not even be a manifest present, the developer could call the install method with an arbitrary id they give their content (i.e. navigator.install('myinstallid123')). If in the future they wanted to add a manifest file to that (non-app) content, they could do so and use the same string they used as an id and the app could continue updating without any issues.

This resolves the concern in a way that makes the API consistent independent of the use case (same/cross-origin) and doesn't require the same-origin to-be-installed-content to have a manifest id or to be a web app. We believe it prevents developers from creating a bad app ecosystem as well.

In the case of cross-origin installations, the requirement is to be an installable app and to require a manifest due to bad actor potential and avoiding a bad site to install any URL. This is achieved by opting into the installation sources field, which is present in a manifest file.

cc @amandabaker @dmurph

dmurph commented 2 months ago

In case it's helpful, I modified my earlier proposal here to match what Diego is proposing after we had a discussion. I am in alignment with Diego here, and that doc goes a little more in depth into the use-cases & edge cases here related to supplying an id field.

diekus commented 1 month ago

gentle ping, would love to continue with work on Web Install! @hober @torgo

diekus commented 1 month ago

for reference, linking here to developer feedback that is outside of the big browser vendors. There is appetite for this feature, and I find it encouraging that in a thread talking about the web not belonging to anyone, it's actual 3P developers the ones stepping up with signs of support. <3

https://github.com/w3ctag/ethical-web-principles/issues/120#issuecomment-2285348765 https://github.com/w3ctag/ethical-web-principles/issues/120#issuecomment-2285431557

jyasskin commented 2 weeks ago

Thanks for bearing with us. Looking at this proposal again from first principles, it seems like a way to reduce the friction between discovering an app and installing it. The web doesn't need any new APIs for someone to build an application repository to search for apps; that's just a filter in a search engine. We don't need a new API to let someone curate the results in such a search engine according to their current trustworthiness. Without this proposal, the quickest route from an app-search results page to installing an app seems to be:

  1. User clicks the result.
  2. Landing page presents an "Install me" button. (The landing page can't just request an installation dialog because of the gesture requirement of the same-origin navigator.install).
  3. User clicks the "Install me" button.
  4. Browser presents the installation dialog.

With this proposal, a browser could eliminate the middle two steps:

  1. User clicks the result.
  2. Browser presents the target app and an installation dialog.

The TAG is split on whether that's potentially an improvement, with a majority thinking it isn't. Given that any given app is installed just once in its lifetime, one click is not a high price. There are several benefits to that: installation is controlled by the origin that will be installed, it doesn't require the creation of a bunch of machinery, and the installation is both attributable and accountable to the correct entity. If you think we need to eliminate that click, your explainer should present some supporting evidence.

If you persist here, and you have UI in mind to deal with all of those issues, we think that a declarative model is likely to work better than the current imperative proposal. You identified a link attribute in your Alternatives Considered section, but maybe a new link relation type would work better than a new target keyword. That gives user agents some flexibility in terms of how they handle the request to install, from just ignoring it and navigating, to doing something more actively.

It is not clear to us why sites need to be able to control which stores can install them. This is the most centralizing aspect of the proposal: if a newly-created store needs to get the approval of hundreds of apps before it can be a viable store, you've created a moat around the incumbents. What would make that necessary in this model?

The proposed navigator.getInstalledApps() sounds plausible on its face, but there are some unresolved issues. It could be awkward when (for privacy reasons) a store shows an app as not-yet-installed even though the user installed it directly or via a different store. But there's a more serious privacy issue in telling stores whether an app has later been uninstalled: how can users be adequately informed about who's getting that information? It's not clear that the cross-origin signal there is justified. Keying off DNT/GPC seems like the wrong tool to use as those relate to something orthogonal. If there's a good justification for exposing uninstallation information, a mechanism like :visited, which exposes 1 target at a time, might be better than the full list returned by the current proposal.

The TAG remains conflicted on this proposal. A number of us are firmly of the view that this feature is unnecessary, both in terms of its justification and in terms of the cost. While that is the prevailing view, others are looking to find ways to enable browser experimentation that minimize the potential harm, especially to users and browsers that don't adopt this change.

Overall, we'd prefer to see this not go ahead at all, but if it does, we'd like to keep talking through the above options or others that might reduce the potential harm.

slightlyoff commented 2 weeks ago

There seems to be some confusion in this thread.

Some folks seem to be conflating browser-facilitated prompting based on browser quality signals with user-initiated flows that come from browser UI. Browsers that support browser-facilitated prompting have long required quality gates, including conformant manifests. The proposal here is explicitly to extend that system to cross-origin prompting.

Browsers that don't provide any sort of developer-facilitated and controlled prompting are a long way from getting any value from navigator.install(), and my suggestion would be that they start by implementing the onbeforeinstallprompt analogue for "Smart Banners" (which require a great deal of developer work, including a stable ID) based on explicit developer signals and quality gates; manifests are a good first-step there.

It only really makes sense for browsers that support developers in promoting their web apps on the same origin to extend that support to cross-origin cases with navigator.install(). Hopefully the TAG can recognise that the UI differences between browser-enhanced promotion and user-initiated, buried UI surfaces material to the success of install rates (as has been continually proven in PWA-supporting browser's data) and therefore categorically different in developer intent and need for API surface area.