Adding a PWA Shortcut to the Desktop

· 2 min read · 383 Words · -Views -Comments

We wanted users to “install” the WebShell as a desktop app. The plan: implement PWA support and leverage the add-to-home-screen experience.

https://static.1991421.cn/2023/2023-02-27-220540.jpeg

PWA Configuration

manifest.webmanifest

Sample: https://github.com/alanhe421/express-demo/blob/781c83b468e6214cf90fa61c66a94249b81125b3/static/xterm.webmanifest

  1. display

    • minimal-ui

    https://static.1991421.cn/2023/2023-02-27-223043.jpeg

    • standalone

    https://static.1991421.cn/2023/2023-02-27-223109.jpeg

  2. name / short_name / display

    • Changing name shows an update prompt after a browser restart; display applies immediately without a prompt.

    https://static.1991421.cn/2023/2023-10-24-124206.jpeg

  3. description

    • Shows on Windows when you hover over the shortcut—keep it short.
    • Updating the manifest doesn’t refresh existing shortcuts; users must reinstall.
  4. theme_color

Update it dynamically via <meta name="theme-color" content="#0066ff"/> if needed.

https://static.1991421.cn/2023/2023-02-27-223225.jpeg

  1. icons
    • Provide 192px/512px sizes; include maskable variants.
  2. screenshots
    • Recommended sizes: 400x822 (narrow) and 1280x676 (wide).
    • Use PNG; WebP didn’t work in our tests.

Register the Service Worker

Example: https://github.com/alanhe421/express-demo/blob/c129ffabc49757302bf3350c607c4dec71a1f29f/static/js/sw.js

Debugging

Chrome incognito disables install prompts and Service Worker logging.

Compatibility

Most modern browsers support PWAs (Firefox, Safari, etc.), though install support varies. Desktop installation works on recent Edge/Chrome releases for Windows and macOS.

Listen for beforeinstallprompt; if it fires, installation is available.

  window.addEventListener('beforeinstallprompt', (e) => {
    // Non-null means installation is available; null means unsupported or already installed.
    window.deferredPrompt = e;
  });

Some Chrome users still reported no prompt—likely due to browser settings. The approach above plus beforeinstallprompt gets us most of the way there.

Update: Safari on macOS Sonoma now shows installation prompts.

Common Questions

  1. Detecting standalone launch:

      function isStandalone() {
        if (window.matchMedia('(display-mode: standalone)').matches || ('standalone' in navigator && (navigator.standalone === true))) {
          return true;
        }
        return false;
      }
    
  2. Detect whether the app is already installed

    • beforeinstallprompt won’t fire if it’s unsupported (Firefox), prerequisites aren’t met, or it’s already installed. There’s no perfect detection.
  3. Programmatically open the installed app from the webpage? No API yet.

  4. Multiple launches

    • Each “Open with” click opens another window; PWAs are still browser tabs under the hood.
  5. Custom install prompt

    • You can add your own UI and trigger the browser’s prompt manually:
      installApp.addEventListener('click', async () => {
        if (deferredPrompt !== null) {
          deferredPrompt.prompt();
          const {outcome} = await deferredPrompt.userChoice;
          if (outcome === 'accepted') {
            window.deferredPrompt = null;
          }
        }
      });
    
  6. Splash screens? Not configurable beyond what the browser provides—simulate it with your own loading animation.

  7. Incognito mode won’t trigger beforeinstallprompt, though Service Workers still run.

  8. HTTPS is mandatory for PWAs.

Example Sites

Examples that support desktop install:

  1. https://www.v2ex.com/
  2. https://youtube.com/
  3. https://twitter.com/

Closing Thoughts

This setup focuses on one PWA feature—adding a desktop entry point.

References

Authors
Developer, digital product enthusiast, tinkerer, sharer, open source lover