0.2.1 • Published 1 year ago

@progressivewebcomponents/pwa-install v0.2.1

Weekly downloads
115
License
MIT
Repository
github
Last release
1 year ago

Published on NPM Published on webcomponents.org

A tiny zero-dependency non-visual native browser web component (custom HTML element and class) that helps implement custom patterns for promoting progressive web apps (PWA) installation.

It's compatible with Google Polymer library data binding.

API

Methods

MethodTypeModifiers
prompt(): ?Promise<Object>async
getInstalledRelatedApps(): ?Promise<Array>async

Properties

PropertyTypeModifiers
isInstallSupported?booleanreadonly
isInstallAvailable?booleanreadonly
platforms?Arrayreadonly
choiceResult?Objectreadonly
isGetInstalledRelatedAppsSupported?booleanreadonly
relatedApps?Arrayreadonly

Attributes

AttributeTypeModifiers
is-install-supported?booleanreadonly
is-install-available?booleanreadonly
is-get-installed-related-apps-supported?booleanreadonly

Events

EventBubblesComposed
pwa-install-availabletruetrue
pwa-install-installingtruetrue
pwa-install-installedtruetrue
pwa-install-errortruetrue
is-install-supported-changedfalsefalse
is-install-available-changedfalsefalse
platforms-changedfalsefalse
choice-result-changedfalsefalse
is-get-installed-related-apps-supported-changedfalsefalse
related-apps-changedfalsefalse

Install

npm i @progressivewebcomponents/pwa-install

Import

Local

JS

import './node_modules/@progressivewebcomponents/pwa-install/pwa-install.js';

See the Customize section for how to use the code below:

import { PWAInstall } from './node_modules/@progressivewebcomponents/pwa-install/pwa-install-class.js';

HTML

<script
  type="module"
  src="./node_modules/@progressivewebcomponents/pwa-install/pwa-install.js">
</script>
<script type="module">
  import './node_modules/@progressivewebcomponents/pwa-install/pwa-install.js';
</script>

See the Customize section for how to use the code below:

<script type="module">
  import { PWAInstall } from './node_modules/@progressivewebcomponents/pwa-install/pwa-install-class.js';
</script>

Import maps

<script type="importmap">
  {
    "imports": {
      "pwa-install": "./node_modules/@progressivewebcomponents/pwa-install/pwa-install.js",
      "pwa-install/": "./node_modules/@progressivewebcomponents/pwa-install/"
    }
  }
</script>

JS

import 'pwa-install';

See the Customize section for how to use the code below:

import { PWAInstall } from 'pwa-install/pwa-install-class.js';

HTML

<script type="module">
  import 'pwa-install';
</script>

See the Customize section for how to use the code below:

<script type="module">
  import { PWAInstall } from 'pwa-install/pwa-install-class.js';
</script>

Dev Servers / Builders

JS

import '@progressivewebcomponents/pwa-install';

See the Customize section for how to use the code below:

import { PWAInstall } from '@progressivewebcomponents/pwa-install/pwa-install-class.js';

HTML

<script type="module">
  import '@progressivewebcomponents/pwa-install';
</script>

See the Customize section for how to use the code below:

<script type="module">
  import { PWAInstall } from '@progressivewebcomponents/pwa-install/pwa-install-class.js';
</script>

CDN

UNPKG

JS

import 'https://unpkg.com/@progressivewebcomponents/pwa-install';

See the Customize section for how to use the code below:

import { PWAInstall } from 'https://unpkg.com/@progressivewebcomponents/pwa-install/pwa-install-class.js';

HTML

<script
  type="module"
  src="https://unpkg.com/@progressivewebcomponents/pwa-install">
</script>
<script type="module">
  import 'https://unpkg.com/@progressivewebcomponents/pwa-install';
</script>

See the Customize section for how to use the code below:

<script type="module">
  import { PWAInstall } from 'https://unpkg.com/@progressivewebcomponents/pwa-install/pwa-install-class.js';
</script>

ESM CDN

JS

import 'https://esm.sh/@progressivewebcomponents/pwa-install';

See the Customize section for how to use the code below:

import { PWAInstall } from 'https://esm.sh/@progressivewebcomponents/pwa-install/pwa-install-class.js';

HTML

<script
  type="module"
  src="https://esm.sh/@progressivewebcomponents/pwa-install">
</script>
<script type="module">
  import 'https://esm.sh/@progressivewebcomponents/pwa-install';
</script>

See the Customize section for how to use the code below:

<script type="module">
  import { PWAInstall } from 'https://esm.sh/@progressivewebcomponents/pwa-install/pwa-install-class.js';
</script>

Skypack

JS

import 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install';

See the Customize section for how to use the code below:

import { PWAInstall } from 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install/pwa-install-class.js';

HTML

<script
  type="module"
  src="https://cdn.skypack.dev/@progressivewebcomponents/pwa-install">
</script>
<script type="module">
  import 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install';
</script>

See the Customize section for how to use the code below:

<script type="module">
  import { PWAInstall } from 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install/pwa-install-class.js';
</script>

Use

HTML

<pwa-install id="a2hs"></pwa-install>

JS

const pwaInstall = document.getElementById('a2hs');
const choiseResult = await pwaInstall.prompt();

const relatedApps = await pwaInstall.getInstalledRelatedApps();
let isInstallSupportedPropertyValue = pwaInstall.isInstallSupported;

let isInstallAvailablePropertyValue = pwaInstall.isInstallAvailable;

let platformsPropertyValue = pwaInstall.platforms;

let choiceResultPropertyValue = pwaInstall.choiceResult;

let isGetInstalledRelatedAppsSupportedPropertyValue = pwaInstall.isGetInstalledRelatedAppsSupported;

let relatedAppsPropertyValue = pwaInstall.relatedApps;
let isInstallSupportedAttributeValue = pwaInstall.hasAttribute('is-install-supported');

let isInstallAvailableAttributeValue = pwaInstall.hasAttribute('is-install-available');

let isGetInstalledRelatedAppsSupportedAttributeValue = pwaInstall.hasAttribute('is-get-installed-related-apps-supported');
pwaInstall.addEventListener('pwa-install-available', handlePWAInstallAvailableEvent);

pwaInstall.addEventListener('pwa-install-installing', handlePWAInstallInstallingEvent);

pwaInstall.addEventListener('pwa-install-installed', handlePWAInstallInstalledEvent);

pwaInstall.addEventListener('pwa-install-error', handlePWAInstallErrorEvent);
const handlePWAInstallAvailableEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handlePWAInstallInstallingEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handlePWAInstallInstalledEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handlePWAInstallErrorEvent = (event) => {
  // Use event.detail.message.error, event.detail.value and/or run any code
}

Events can be used to collect telemetry on (promoting) PWA installation and send it to e.g. Google Analytics:

const handlePWAInstallAvailableEvent = (event) => {
  window.gtag?.('event', 'pwa-install', {
    'state': 'available',
    'platforms': event.detail.value,
  });
}

const handlePWAInstallInstallingEvent = (event) => {
  window.gtag?.('event', 'pwa-install', {
    'state': 'installing',
    'outcome': event.detail.value?.outcome,
    'platform': event.detail.value?.platform,
  });
}

const handlePWAInstallInstalledEvent = (event) => {
  window.gtag?.('event', 'pwa-install', {
    'state': 'installed',
    'platform': event.detail.value?.platform,
  });
}

const handlePWAInstallErrorEvent = (event) => {
  window.gtag?.('event', 'pwa-install', {
    'state': 'error',
    'error': event.detail.message.error,
    'platform': event.detail.value?.platform,
  });
}
pwaInstall.addEventListener('is-install-supported-changed', handleIsInstallSupportedPropertyChangedEvent);

pwaInstall.addEventListener('is-install-available-changed', handleIsInstallAvailablePropertyChangedEvent);

pwaInstall.addEventListener('platforms-changed', handlePlatformsPropertyChangedEvent);

pwaInstall.addEventListener('choice-result-changed', handleChoiceResultPropertyChangedEvent);

pwaInstall.addEventListener('is-get-installed-related-apps-supported-changed', handleIsGetInstalledRelatedAppsSupportedPropertyChangedEvent);

pwaInstall.addEventListener('related-apps-changed', handleRelatedAppsPropertyChangedEvent);
const handleIsInstallSupportedPropertyChangedEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handleIsInstallAvailablePropertyChangedEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handlePlatformsPropertyChangedEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handleChoiceResultPropertyChangedEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handleIsGetInstalledRelatedAppsSupportedPropertyChangedEvent = (event) => {
  // Use event.detail.value and/or run any code
}

const handleRelatedAppsPropertyChangedEvent = (event) => {
  // Use event.detail.value and/or run any code
}

Events can be used to update the property values:

const handleIsInstallSupportedPropertyChangedEvent = (event) => {
  isInstallSupportedPropertyValue = event.detail.value;
}

const handleIsInstallAvailablePropertyChangedEvent = (event) => {
  isInstallAvailablePropertyValue = event.detail.value;
}

const handlePlatformsPropertyChangedEvent = (event) => {
  platformsPropertyValue = event.detail.value;
}

const handleChoiceResultPropertyChangedEvent = (event) => {
  choiceResultPropertyValue = event.detail.value;
}

const handleIsGetInstalledRelatedAppsSupportedPropertyChangedEvent = (event) => {
  isGetInstalledRelatedAppsSupportedPropertyValue = event.detail.value;
}

const handleRelatedAppsPropertyChangedEvent = (event) => {
  relatedAppsPropertyValue = event.detail.value;
}

CSS

#a2hs[is-install-supported]

#a2hs[is-install-available]

#a2hs[is-get-installed-related-apps-supported]

CSS attribute selectors can be used to show/hide and/or style other HTML elements e.g. the UI for promoting PWA installation:

<pwa-install id="a2hs"></pwa-install>

<button
  id="install"
  onclick="document.getElementById('a2hs').prompt()">
    Install
</button>
#install {
  visibility: hidden;
}

:has(#a2hs[is-install-available]) #install {
  visibility: visible;
}

Lit

<pwa-install
  id="a2hs"

  @pwa-install-available="${this.handlePWAInstallAvailableEvent}"
  @pwa-install-installing="${this.handlePWAInstallInstallingEvent}"
  @pwa-install-installed="${this.handlePWAInstallInstalledEvent}"
  @pwa-install-error="${this.handlePWAInstallErrorEvent}"

  @is-install-supported-changed="${this.handleIsInstallSupportedPropertyChangedEvent}"
  @is-install-available-changed="${this.handleIsInstallAvailablePropertyChangedEvent}"
  @platforms-changed="${this.handlePlatformsPropertyChangedEvent}"
  @choice-result-changed="${this.handleChoiceResultPropertyChangedEvent}"
  @is-get-installed-related-apps-supported-changed="${this.handleIsGetInstalledRelatedAppsSupportedPropertyChangedEvent}"
  @related-apps-changed="${this.handleRelatedAppsPropertyChangedEvent}">
</pwa-install>
const pwaInstall = this.shadowRoot.getElementById('a2hs');

Polymer

<pwa-install
  id="a2hs"

  is-install-supported="{{isInstallSupportedPropertyValue}}"
  is-install-available="{{isInstallAvailablePropertyValue}}"
  platforms="{{platformsPropertyValue}}"
  choice-result="{{choiceResultPropertyValue}}"
  is-get-installed-related-apps-supported="{{isGetInstalledRelatedAppsSupportedPropertyValue}}"
  related-apps="{{relatedAppsPropertyValue}}"

  on-pwa-install-available="handlePWAInstallAvailableEvent"
  on-pwa-install-installing="handlePWAInstallInstallingEvent"
  on-pwa-install-installed="handlePWAInstallInstalledEvent"
  on-pwa-install-error="handlePWAInstallErrorEvent"

  on-is-install-supported-changed="handleIsInstallSupportedPropertyChangedEvent"
  on-is-install-available-changed="handleIsInstallAvailablePropertyChangedEvent"
  on-platforms-changed="handlePlatformsPropertyChangedEvent"
  on-choice-result-changed="handleChoiceResultPropertyChangedEvent"
  on-is-get-installed-related-apps-supported-changed="handleIsGetInstalledRelatedAppsSupportedPropertyChangedEvent"
  on-related-apps-changed="handleRelatedAppsPropertyChangedEvent">
</pwa-install>
const pwaInstall = this.$.a2hs;

Property values can be used to show/hide and/or change the state of other HTML elements e.g. the UI for promoting PWA installation:

<pwa-install
  id="a2hs"
  is-install-supported="{{isInstallSupportedPropertyValue}}"
  is-install-available="{{isInstallAvailablePropertyValue}}">
</pwa-install>

<button
  on-click="handleInstallButtonClick"
  hidden$="[[!isInstallSupportedPropertyValue]]"
  disabled$="[[!isInstallAvailablePropertyValue]]">
    Install
</button>
handleInstallButtonClick() {
  this.$.a2hs.prompt();
}

Customize

PWAInstall class can be imported without registering <pwa-install> custom HTML element. It can be used to register the web component with a different custom HTML element name:

import { PWAInstall } from 'pwa-install/pwa-install-class.js';

customElements.define('your-custom-element-name', PWAInstall);

or customize the web component:

import { PWAInstall } from 'pwa-install/pwa-install-class.js';

class YourCustomElement extends PWAInstall {
  // Add or override methods, properties, attributes, events, etc.
}

customElements.define('your-custom-element-name', YourCustomElement);
<your-custom-element-name id="a2hs"></your-custom-element-name>

Further reading

Patterns for promoting PWA installation

Native app install prompt

Is your app installed? getInstalledRelatedApps() will tell you!

Detect if your native app is installed from your web site

What does it take to be installable?

Add a web app manifest