Skip to content

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

Notifications You must be signed in to change notification settings

ProgressiveWebComponents/pwa-install

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Published on NPM Published on webcomponents.org

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

It's compatible with Google Polymer library data binding.

Table of contents

API

Methods

Method Type Modifiers
prompt (): ?Promise<Object> async
getInstalledRelatedApps (): ?Promise<Array> async

Properties

Property Type Modifiers
isInstallSupported ?boolean readonly
isInstallAvailable ?boolean readonly
platforms ?Array readonly
choiceResult ?Object readonly
isGetInstalledRelatedAppsSupported ?boolean readonly
relatedApps ?Array readonly

Attributes

Attribute Type Modifiers
is-install-supported ?boolean readonly
is-install-available ?boolean readonly
is-get-installed-related-apps-supported ?boolean readonly

Events

Event Bubbles Composed
pwa-install-available true true
pwa-install-installing true true
pwa-install-installed true true
pwa-install-error true true
is-install-supported-changed false false
is-install-available-changed false false
platforms-changed false false
choice-result-changed false false
is-get-installed-related-apps-supported-changed false false
related-apps-changed false false

Install

npm i @progressivewebcomponents/pwa-install

Import

Local

JS

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

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>
Advanced usage

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';
Advanced usage

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>
Advanced usage

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';
Advanced usage

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>
Advanced usage

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';
Advanced usage

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>
Advanced usage

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';
Advanced usage

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>
Advanced usage

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';
Advanced usage

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>
Advanced usage

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
}
Use case

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
}
Use case

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]
Use case

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;
Use case

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="handleInstallButtonClickEvent"
  hidden$="[[!isInstallSupportedPropertyValue]]"
  disabled$="[[!isInstallAvailablePropertyValue]]"
>
  Install
</button>
handleInstallButtonClickEvent() {
  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

About

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

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published