@khmyznikov/pwa-install

repository·main·Indexed 21 days ago

https://github.com/khmyznikov/pwa-install

A lightweight (28kB compressed) web component that provides enhanced PWA installation dialogs and 'Add to Home Screen' instructions. It bridges the gap for browsers like Safari and Firefox that lack native installation prompts, offering a consistent experience across iOS, Android, and Desktop. The component supports localization for numerous languages, custom styling via CSS variables for Apple templates, and integration with modern frameworks like React, Angular, and Svelte.

Tokens
4.9K
Snippets
19
Records
22
Agent score
75%

What's inside @khmyznikov/pwa-install

  1. Import and use the <pwa-install> web component

    main

    After installing, import the package to register the <pwa-install> custom element. You can then use it in your HTML like any other web component. It works with modern frameworks (React, Angular, Svelte, etc.) without polyfills.

    import '@khmyznikov/pwa-install';
    <pwa-install></pwa-install>
  2. Use Async Mode for Chromium browsers

    main

    If you need to target Chromium browsers but want to postpone component mounting, you can manually capture the beforeinstallprompt event and pass it to the component's externalPromptEvent property.

    // 1. Capture event immediately
    window.addEventListener('beforeinstallprompt', (e) => {
      e.preventDefault();
      e.stopPropagation();
      e.stopImmediatePropagation();
      window.promptEvent = e;
    });
    
    // 2. Later, pass the event to the component via the property
    const pwaInstall = document.getElementById("pwa-install");
    pwaInstall.externalPromptEvent = window.promptEvent;
  3. Configure TypeScript for <pwa-install>

    main

    To ensure proper type checking for PWA-related events and manifests, update your tsconfig.json with the following settings:

    "compilerOptions": {
      "moduleResolution": "Bundler",
      "types": ["dom-chromium-installation-events", "web-app-manifest"]
    }
  4. Use the PWAInstallElement web component

    main

    The PWAInstallElement is a Lit-based web component that provides a UI for prompting users to install your Progressive Web App (PWA). It handles platform-specific logic for Chromium/Android (using the beforeinstallprompt event) and Apple devices (providing manual instructions/galleries).

    To use it, include the <pwa-install> custom element in your HTML and configure its properties via attributes.

    <pwa-install
      manifest-url="/manifest.json"
      name="My App"
      description="A great app"
      install-description="Tap the share button and select 'Add to Home Screen'"
    ></pwa-install>
  5. Access <pwa-install> properties and methods

    main

    You can interact with the component instance via JavaScript to check its state or trigger actions.

    const pwaInstall = document.querySelector('pwa-install');
    
    // Read-only properties
    console.log(pwaInstall.isUnderStandaloneMode);
    console.log(pwaInstall.isInstallAvailable);
    
    // Methods
    pwaInstall.install();
    pwaInstall.hideDialog();
    pwaInstall.showDialog();
    // Chromium only
    const relatedApps = await pwaInstall.getInstalledRelatedApps();
  6. Customize styles for the Apple template

    main

    Currently, only the Apple template supports custom styling via the --tint-color CSS variable. You can set this using the styles property (as an object) or the styles attribute (as a JSON string).

    // As property (object)
    const pwaInstall = document.querySelector('pwa-install');
    pwaInstall.styles = { '--tint-color': '#6366f1' };
    
    // Or as attribute via JavaScript
    pwaInstall.setAttribute('styles', JSON.stringify({ '--tint-color': '#6366f1' }));
  7. Configure custom-elements-manifest.config.mjs

    main

    The custom-elements-manifest.config.mjs file is used to configure the Custom Elements Manifest (CEM) generation process for the project. It defines which files to analyze, how to handle specific libraries like litelement, and how to output the resulting manifest.

    Available configuration options include:

    • globs: An array of glob patterns specifying the files to analyze (e.g., ['src/index.ts']).
    • exclude: An array of glob patterns to exclude from analysis.
    • outdir: The directory where the CEM will be output.
    • dev: Boolean. If true, enables extra logging for development.
    • watch: Boolean. If true, runs in watch mode, re-running on file changes.
    • dependencies: Boolean. If true, includes third-party custom elements manifests.
    • packagejson: Boolean. If true, outputs the CEM path to package.json (defaults to true).
    • litelement: Boolean. Enables special handling for litelement components.
    • catalyst: Boolean. Enables special handling for catalyst.
    • fast: Boolean. Enables special handling for fast.
    • stencil: Boolean. Enables special handling for stencil.
    • plugins: An array of custom plugins to provide additional functionality (e.g., reactify).
    export default {
      /** Globs to analyze */
      globs: ['src/index.ts'],
      /** Enable special handling for litelement */
      litelement: true,
    };
  8. Listen to <pwa-install> events

    main

    The component emits several events to track the installation lifecycle.

    Warning: pwa-install-success-event, pwa-install-fail-event, and pwa-user-choice-result-event are only available in Chromium-based browsers; iOS does not support them.

    ```html
    <script type="text/javascript">
      var pwaInstall = document.getElementsByTagName('pwa-install')[0];
    
      pwaInstall.addEventListener('pwa-install-success-event', (event) => {
        console.log(event.detail.message);
      });
    </script>

    Supported Events:

    • pwa-install-success-event
    • pwa-install-fail-event
    • pwa-install-available-event
    • pwa-user-choice-result-event
    • pwa-install-how-to-event
    • pwa-install-gallery-event
  9. Configure <pwa-install> with attributes

    main

    You can customize the behavior and content of the installation dialog using HTML attributes.

    Note: Boolean attributes must be removed to act as false. If you provide a manifest file, it is recommended not to use name, description, or icon params as they will override the manifest values.

    <pwa-install
      manual-apple
      manual-chrome
      disable-chrome
      disable-close
      use-local-storage
      install-description="Custom call to install text"
      disable-install-description
      disable-screenshots
      disable-screenshots-apple
      disable-screenshots-chrome
      manual-how-to
      disable-android-fallback
      manifest-url="/manifest.json"
      name="PWA"
      description="Progressive web application"
      icon="/icon.png">
    </pwa-install>
  10. Call PWAInstallElement methods

    main

    You can interact with the PWAInstallElement instance programmatically via its public methods:

    • install(): Triggers the installation process. On Apple devices, this shows instructions; on Chromium, it triggers the beforeinstallprompt.
    • hideDialog(): Hides the installation dialog and persists the preference if useLocalStorage is enabled.
    • showDialog(forced?: boolean): Shows the installation dialog. If forced is true, it sets isInstallAvailable to true.
    • getInstalledRelatedApps(): Returns a Promise<IRelatedApp[]> containing information about related apps already installed on the device.
    const pwaElement = document.querySelector('pwa-install');
    
    // Trigger installation
    pwaElement.install();
    
    // Manually show the dialog
    pwaElement.showDialog(true);
    
    // Get related apps
    const relatedApps = await pwaElement.getInstalledRelatedApps();
  11. Use the <pwa-install> component in JSX/React

    main

    The <pwa-install> element is available as a custom JSX element. When using it in React or other JSX-compatible environments, you can pass standard HTML attributes, React ref attributes, and specific PWA installation properties. The component accepts children as a valid prop, allowing you to wrap content inside the installation prompt UI.

    // Example usage in a React component
    function App() {
      return (
        <pwa-install 
          some-pwa-attribute="value"
          className="custom-class"
        >
          Install our app for the best experience!
        </pwa-install>
      );
    }