I'd like to see a sub-module which provides a block which can trigger an installation action.

iOS does does not support install banners and they are easily dismissed on Android. Maximiliano Firtman discusses this suggestion along with other good stuff in the video below. (at about 16 minutes).

https://www.youtube.com/watch?v=cybhV88KLfI

Comments

MrPaulDriver created an issue. See original summary.

mrpauldriver’s picture

Title: Provide a PWA installation button block » Provide a PWA installation button block (sub-module)
christophweber’s picture

It's funny you should mention that, I was thinking along very similar lines last night. My concern is that iOS does not provide install events in any form, so the code shown in the video would work only on Android, plus desktop Chrome and Edge. For iOS users the install via native share functionality remains the only option, and unless I am missing something, the only help we can provide those users is a message or block with appropriate text to guide them.
Long story short, the proposed submodule would need to address both user/browser populations. I'm hoping Apple will soon make that obsolete, but the this year's WWDC coverage didn't give me cause to expect much.

rupl’s picture

mrpauldriver’s picture

Apple's financial interest in the App Store isn't going away, so we have to presume that they will resist PWAs for as long as they can. Forget them.

In the meantime, with the help of some device detection (or a another module which provides this) we provide a block which installs the PWA after a click event for Android users, and for iOS users, provides a message containing a brief installation guide.

rupl’s picture

No device detection in a module called “Progressive Web App” please! The “Progressive” means that some or all of it will not work in every browser. That’s the reality of it.

The markup for the block can exist on a page hidden, and only activate itself when the appropriate event listener is caught. That’s what progressive enhancement is about. See my notes and links in the older issue.

With a new web technology, it’s easy to get cornered by the mindset that you have to provide an identical UX in every platform. But by relying on the official tools/methods and not hacking around them, you actually encourage positive pressure on lagging platforms like iOS to implement the pieces that you are using.

mrpauldriver’s picture

It is interesting that this can be done without device detection. Great!

I am not asking for identical UX for every platform, but rather, for alternative routes toward the objective of getting an app installed.

Details aside, it does sound like we want the same thing.

rupl’s picture

I finally watched the YouTube and even though I filed the other issue a year ago, the 2019 JSConf talk is about the same event listener: beforeinstallprompt.

The fact that it's an event listener means that certain browsers can listen and react to it. It's exactly the same as you might write a much more common click event listener. Until a browser both implements the event as a feature, then emits events when individual visitors meet the criteria, the listener code will lay dormant.

Here's a technical how-to: https://developers.google.com/web/updates/2018/06/a2hs-updates

rupl’s picture

So in terms of how I would recommend this be done:

  • Define a block in code. The block has simple markup including a <button> that reads "Add to Homescreen" (or maybe a configurable message) and also a "No thanks" button.
  • This block should contain attributes and styles to make it invisible to ALL users, including screen readers and the like: display: none, aria-hidden, etc
  • In client-side JS (NOT the SW) there needs to be an event listener for beforeinstallprompt that activates this block's display and allows the user to find it. It could be styled as a modal, placed within content, etc. That part is up to individual implementors.
  • Once the prompt is accepted/dismissed, the callback for the event will finish running, and the app will be either added to homescreen or dismissed for a certain amount of time.
mrpauldriver’s picture

Configurable message would be good, allowing phrases such as "Install App"

For my use case I would prefer not to have a "No thanks" button, as my project is very much about installing as a mobile pwa. Not that I would compel visitors to install it and I would probably place the block in an offcanvas region so that it would not degrade normal usage of the site

If a modal, then yes it would have to be dismissable. Like most people, I hate automatic modals and would not use one personally.

// Aside
Thinking more about this. Is there also a case for back button and a reload button and as well?

- In fullscreen or standalone mode there are no back and forward navigation buttons (although latest version of Safari does have a swipe gesture).

- In the case of Android there is a 'swipe down to reload' action, but as far as I know there is no such gesture for iOS.

If you agree with the button idea, there would be a case naming the submodule pwa_buttons rather than (say) pwa_installer

rupl’s picture

I'd still provide a way to dismiss a prompt with a definitive "No" because a generic solution should provide good defaults and a widely-applicable UX. The beforeinstallprompt event listener can react to both a positive and negative reaction (e.g. by setting a 3-month timer to ask again in the future if you clicked "No").

You can always hide the "No" button with CSS.

There's not a use case for back/next. The manifest.json uses browser chrome by default specifically so we don't have to provide over-complicated solutions like rebuilding browser chrome. If people want to customize to their hearts' content, they do have the option available.

mrpauldriver’s picture

All good points @rupl

danreb’s picture

I've implemented something like this in my project but the code is manually added to page template. Will provide the code and/or convert it to a sub-module and send it here for review in the following days.

I had open a new feature request earlier and missed this thread, sorry for that.

alexborsody’s picture

Cool looking forward to seeing that.

naveenvalecha’s picture

Title: Provide a PWA installation button block (sub-module) » Provide a PWA installation button block

As there's a new submodule got introduced into the #3066848: Emit metatags for iOS from a submodule It would be better to leverage that. Retitling to reflect it better.
@danreb
I would love to see how it's being implemented.

mrpauldriver’s picture

As well as a block, I am wondering if a text link can be provided for inclusion as a hyperlink in an existing block?

rupl’s picture

Yes, a text link can be included, although an HTML <button> is the correct element to use. From there, you'd implement an event listener for beforeinstallprompt and write any code you want.

mrpauldriver’s picture

I am liking the idea of some button code which could be included within an existing block.

jeni_dc’s picture

Status: Active » Needs review
StatusFileSize
new6.74 KB

I've taken an initial stab at this. There's definitely still stuff to do but this gives us a start to determine the direction and all the features we'd want in this.

This patch adds a new "pwa_a2hs" module. That module provides a block to output a button that triggers an A2HS prompt when the PWA criteria are met. This is essentially what's described here:

https://developers.google.com/web/fundamentals/app-install-banners/

The block has two fields, one for an introduction and one for the button text. Neither the introduction text or the button are shown unless the PWA criteria are met, and the current browser supports adding a PWA. The JS targets the markup in the included template, to show the introduction text and write the button to the page.

If the PWA criteria aren't met, or the browser doesn't support adding PWAs, or the beforeinstallprompt event doesn't fire, nothing is shown. Well, nothing from the block config is currently shown like the intro text or button, but the block title may still be shown. That's still something to take care of.

The intro text is printed in the template, the button text is added through JS settings to the button which is added in the beforeinstallprompt event. So there's never a button hidden in the block if the criteria aren't met.

The JS can allow for things to happen if a user accepts or denies the browser prompt to install the app. Right now it's just logging to the console. There are currently no other settings to show/hide the block, or set time limits or anything else. All this currently does is add a block, and display a message and a button that will trigger an A2HS prompt if it's available.

christophweber’s picture

I like where this is headed, thank you jeni_dc!
Question: What happens after an install event (yes button clicked)? Does this user ever see the block again, in their regular browser and/or the installed PWA? (Remember, in Safari those are different browser contexts.)

Also, I think a block can be preconfigured to hide the block title, I just don’t have the specifics handy.

jeni_dc’s picture

From what I can tell with some of the testing I've done, when a user has the app installed the beforeinstallprompt event doesn't fire, so the block content won't show. It's that event that should control the whole thing, without it there's no need for the block content to ever show.

Immediately after the user installs the app we can do other things, too. But there's nothing included just yet like that in the module, except for logging to the console for testing. One idea is to hide the entire block as soon as the user installs it. On the next page load the beforeinstallprompt event won't fire, so they won't see it again.

There's a few ways to get around the block title, or other block markup, that will need addressing at some point. We'd really want the entire block to be hidden, not just the title, to make sure it doesn't create theming issues. Things like empty block wrappers can throw off margins, etc, so that will need to be tackled. The title is also useful, and a standard part of Drupal blocks, so should be a part of what gets shown or hidden. One idea is to preprocess the block to add a class or other attribute to target it, or provide a template for that specific block we can target.

mrpauldriver’s picture

Maximiliano Firtman is a bit of a PWA expert and wrote about browser installation his article Progressive Web Apps in 2020

The recent news in this area is that the Web App Manifest spec is probably going to remove the beforeinstallprompt event from the recommendation and it will become a Chromium-only feature.

Probably worth a read.

jeni_dc’s picture

This is always going to be a moving target, but for now the beforeinstallprompt really is the only way to get something like this to work. I haven't seen any other recommendations or methods for achieving something similar. If anyone knows of any, please share them!

For Safari/iOS devices the only thing I've come across is:

https://github.com/JacobDB/pwa-install-prompt

But all that does is show a message instructing the user on how to install the app, it doesn't trigger anything that will install it. We could possibly add that ability into the block and only show it for iOS devices.

That linked article also states:

The ability to install a PWA from our user interface is not going to appear in Safari or Firefox

So that pretty much means no buttons at all, and only show a block with instructions. Which you could really already do with a basic block.

Given how there's so many different ways browsers and devices support PWAs, trying to cover every scenario really isn't an option. So for now I'd say roll out what we can to get this out there (I need it for a project now and the client is happy with the button) and then if the dust ever settles on this or we see new methods appear this year, then adjust as needed.

jeni_dc’s picture

StatusFileSize
new6.83 KB

I was having an issue with the button getting added multiple times (54!) to pages that might have ajax or other calls going on. Here's a new patch that adds using jQuery once to make sure the button is only added one time.

I don't do a lot of contrib JS, and I was trying to keep this to vanilla JS, so I'm not sure if there's any guidelines for mixing in jQuery like this or if it should all be moved over to jQuery. I've added the jQuery dependencies to the library. I had tried to get the button to only appear once keeping it all vanilla JS, but couldn't get it working, jQuery once just worked the first time.

New patch attached.

mrpauldriver’s picture

I went down the instructional route with some help text inside a collapsible block.

Demo here: https://staging.schoolpwa.org

afagioli’s picture

Thanks jeni_dc for that precious patch.
Working fine to me.

Worth to say that - once patched - you have to enable the "Progressive Web Add to Home Screen" module first.
At that point you have that block. Cool!

afagioli’s picture

Any mantainer merging patch to module?
Thanks

afagioli’s picture

Tested https://www.drupal.org/project/pwa/issues/3063345#comment-13444312 on mobile:
Android >Chrome = works
Android >Internet Samsung = works
Android >Firefox = no block exposed
Iphone (version ???) = no block exposed

jeni_dc’s picture

@afagioli, this most likely will never work across all browsers and will only work in browsers where the beforeinstallprompt event is supported. I'd recommend reading through previous comments and the links they contain about how we ended up with what's there, and what is working, and what's likely to not work.

afagioli’s picture

jeni_dc, see my #28 as recap
Thanks!

tyler36’s picture

As of 2021-02-24, support for BeforeInstallPromptEvent
CanIUse

tyler36’s picture

alexborsody’s picture

Status: Needs review » Reviewed & tested by the community

  • AlexBorsody committed ab9aeb6 on 8.x-1.x authored by jeni_dc
    Issue #3063345 by jeni_dc, tyler36, MrPaulDriver, rupl, afagioli,...
alexborsody’s picture

Status: Reviewed & tested by the community » Fixed
alexborsody’s picture

Status: Fixed » Closed (fixed)
zenimagine’s picture