Pwa install
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
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](https://web.dev/articles/promote-install). The project is written primarily in JavaScript, first published in 2019. Key topics include: a2hs, api, custom-element, es-module, esm.
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
shnpm i @progressivewebcomponents/pwa-install
Import
Local
JS
<details> <summary>Advanced usage</summary>jsimport './node_modules/@progressivewebcomponents/pwa-install/pwa-install.js';
See the Customize section for how to use the code below:
</details>jsimport { PWAInstall } from './node_modules/@progressivewebcomponents/pwa-install/pwa-install-class.js';
HTML
html<script type="module" src="./node_modules/@progressivewebcomponents/pwa-install/pwa-install.js" > </script>
<details> <summary>Advanced usage</summary>html<script type="module"> import './node_modules/@progressivewebcomponents/pwa-install/pwa-install.js'; </script>
See the Customize section for how to use the code below:
</details>html<script type="module"> import { PWAInstall } from './node_modules/@progressivewebcomponents/pwa-install/pwa-install-class.js'; </script>
Import maps
html<script type="importmap"> { "imports": { "pwa-install": "./node_modules/@progressivewebcomponents/pwa-install/pwa-install.js", "pwa-install/": "./node_modules/@progressivewebcomponents/pwa-install/" } } </script>
JS
<details> <summary>Advanced usage</summary>jsimport 'pwa-install';
See the Customize section for how to use the code below:
</details>jsimport { PWAInstall } from 'pwa-install/pwa-install-class.js';
HTML
<details> <summary>Advanced usage</summary>html<script type="module"> import 'pwa-install'; </script>
See the Customize section for how to use the code below:
</details>html<script type="module"> import { PWAInstall } from 'pwa-install/pwa-install-class.js'; </script>
Dev Servers / Builders
JS
<details> <summary>Advanced usage</summary>jsimport '@progressivewebcomponents/pwa-install';
See the Customize section for how to use the code below:
</details>jsimport { PWAInstall } from '@progressivewebcomponents/pwa-install/pwa-install-class.js';
HTML
<details> <summary>Advanced usage</summary>html<script type="module"> import '@progressivewebcomponents/pwa-install'; </script>
See the Customize section for how to use the code below:
</details>html<script type="module"> import { PWAInstall } from '@progressivewebcomponents/pwa-install/pwa-install-class.js'; </script>
CDN
UNPKG
JS
<details> <summary>Advanced usage</summary>jsimport 'https://unpkg.com/@progressivewebcomponents/pwa-install';
See the Customize section for how to use the code below:
</details>jsimport { PWAInstall } from 'https://unpkg.com/@progressivewebcomponents/pwa-install/pwa-install-class.js';
HTML
html<script type="module" src="https://unpkg.com/@progressivewebcomponents/pwa-install" > </script>
<details> <summary>Advanced usage</summary>html<script type="module"> import 'https://unpkg.com/@progressivewebcomponents/pwa-install'; </script>
See the Customize section for how to use the code below:
</details>html<script type="module"> import { PWAInstall } from 'https://unpkg.com/@progressivewebcomponents/pwa-install/pwa-install-class.js'; </script>
ESM CDN
JS
<details> <summary>Advanced usage</summary>jsimport 'https://esm.sh/@progressivewebcomponents/pwa-install';
See the Customize section for how to use the code below:
</details>jsimport { PWAInstall } from 'https://esm.sh/@progressivewebcomponents/pwa-install/pwa-install-class.js';
HTML
html<script type="module" src="https://esm.sh/@progressivewebcomponents/pwa-install" > </script>
<details> <summary>Advanced usage</summary>html<script type="module"> import 'https://esm.sh/@progressivewebcomponents/pwa-install'; </script>
See the Customize section for how to use the code below:
</details>html<script type="module"> import { PWAInstall } from 'https://esm.sh/@progressivewebcomponents/pwa-install/pwa-install-class.js'; </script>
Skypack
JS
<details> <summary>Advanced usage</summary>jsimport 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install';
See the Customize section for how to use the code below:
</details>jsimport { PWAInstall } from 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install/pwa-install-class.js';
HTML
html<script type="module" src="https://cdn.skypack.dev/@progressivewebcomponents/pwa-install" > </script>
<details> <summary>Advanced usage</summary>html<script type="module"> import 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install'; </script>
See the Customize section for how to use the code below:
</details>html<script type="module"> import { PWAInstall } from 'https://cdn.skypack.dev/@progressivewebcomponents/pwa-install/pwa-install-class.js'; </script>
Use
HTML
html<pwa-install id="a2hs"></pwa-install>
JS
jsconst pwaInstall = document.getElementById('a2hs');
jsconst choiseResult = await pwaInstall.prompt(); const relatedApps = await pwaInstall.getInstalledRelatedApps();
jslet isInstallSupportedPropertyValue = pwaInstall.isInstallSupported; let isInstallAvailablePropertyValue = pwaInstall.isInstallAvailable; let platformsPropertyValue = pwaInstall.platforms; let choiceResultPropertyValue = pwaInstall.choiceResult; let isGetInstalledRelatedAppsSupportedPropertyValue = pwaInstall.isGetInstalledRelatedAppsSupported; let relatedAppsPropertyValue = pwaInstall.relatedApps;
jslet isInstallSupportedAttributeValue = pwaInstall.hasAttribute('is-install-supported'); let isInstallAvailableAttributeValue = pwaInstall.hasAttribute('is-install-available'); let isGetInstalledRelatedAppsSupportedAttributeValue = pwaInstall.hasAttribute('is-get-installed-related-apps-supported');
jspwaInstall.addEventListener('pwa-install-available', handlePWAInstallAvailableEvent); pwaInstall.addEventListener('pwa-install-installing', handlePWAInstallInstallingEvent); pwaInstall.addEventListener('pwa-install-installed', handlePWAInstallInstalledEvent); pwaInstall.addEventListener('pwa-install-error', handlePWAInstallErrorEvent);
jsconst 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:
jsconst 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, }); }
jspwaInstall.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);
jsconst 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:
jsconst 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
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:
html<pwa-install id="a2hs"></pwa-install> <button id="install" onclick="document.getElementById('a2hs').prompt()" > Install </button>
css#install { visibility: hidden; } :has(#a2hs[is-install-available]) #install { visibility: visible; }
Lit
html<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>
jsconst pwaInstall = this.shadowRoot.getElementById('a2hs');
Polymer
html<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>
jsconst 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:
html<pwa-install id="a2hs" is-install-supported="{{isInstallSupportedPropertyValue}}" is-install-available="{{isInstallAvailablePropertyValue}}" > </pwa-install> <button on-click="handleInstallButtonClickEvent" hidden$="[[!isInstallSupportedPropertyValue]]" disabled$="[[!isInstallAvailablePropertyValue]]" > Install </button>
jshandleInstallButtonClickEvent() { 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:
jsimport { PWAInstall } from 'pwa-install/pwa-install-class.js'; customElements.define('your-custom-element-name', PWAInstall);
or customize the web component:
jsimport { 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);
html<your-custom-element-name id="a2hs"></your-custom-element-name>
Further reading
Patterns for promoting PWA installation
Is your app installed? getInstalledRelatedApps() will tell you!
Detect if your native app is installed from your web site
Contributors
Showing top 1 contributor by commit count.
