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
}
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;
}
#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;
}
<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;
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();
}
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