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.
| Method | Type | Modifiers |
|---|---|---|
prompt |
(): ?Promise<Object> |
async |
getInstalledRelatedApps |
(): ?Promise<Array> |
async |
| Property | Type | Modifiers |
|---|---|---|
isInstallSupported |
?boolean |
readonly |
isInstallAvailable |
?boolean |
readonly |
platforms |
?Array |
readonly |
choiceResult |
?Object |
readonly |
isGetInstalledRelatedAppsSupported |
?boolean |
readonly |
relatedApps |
?Array |
readonly |
| Attribute | Type | Modifiers |
|---|---|---|
is-install-supported |
?boolean |
readonly |
is-install-available |
?boolean |
readonly |
is-get-installed-related-apps-supported |
?boolean |
readonly |
| 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 |
npm i @progressivewebcomponents/pwa-install
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';
<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>
<script type="importmap"> { "imports": { "pwa-install": "./node_modules/@progressivewebcomponents/pwa-install/pwa-install.js", "pwa-install/": "./node_modules/@progressivewebcomponents/pwa-install/" } } </script>
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';
<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>
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';
<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>
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';
<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>
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';
<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>
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';
<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>
<pwa-install id="a2hs"></pwa-install>
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; }
#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; }
<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');
<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="handleInstallButtonClickEvent" hidden$="[[!isInstallSupportedPropertyValue]]" disabled$="[[!isInstallAvailablePropertyValue]]" > Install </button>
handleInstallButtonClickEvent() { this.$.a2hs.prompt(); }
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>
Patterns for promoting PWA installation
Is your app installed? getInstalledRelatedApps() will tell you!
Detect if your native app is installed from your web site