From fade4c3ae50a8ee4fd9f5678280309dfc8ec6045 Mon Sep 17 00:00:00 2001 From: Spencer Flagg Date: Thu, 23 Apr 2026 20:38:08 +0200 Subject: [PATCH] fix: attach PWA install click handler at render time, not conditionally beforeinstallprompt fires asynchronously after renderLanding() runs, so the click handler was never attached when the prompt arrived late. Always attach the handler and check deferredInstallPrompt at click time. --- frontend/public/js/app.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/public/js/app.js b/frontend/public/js/app.js index 3fc4986..4e4fd04 100644 --- a/frontend/public/js/app.js +++ b/frontend/public/js/app.js @@ -116,22 +116,22 @@ function renderLanding() { const btn = app.querySelector('[data-install-btn]'); const hint = app.querySelector('[data-install-hint]'); - if (deferredInstallPrompt) { - wrap.hidden = false; - btn.addEventListener('click', async () => { + // Show immediately if we already have the prompt or are on iOS + if (deferredInstallPrompt || isIOS) wrap.hidden = false; + + // Always attach handler — check state at click time (handles async beforeinstallprompt) + btn.addEventListener('click', async () => { + if (deferredInstallPrompt) { deferredInstallPrompt.prompt(); const { outcome } = await deferredInstallPrompt.userChoice; if (outcome === 'accepted') { deferredInstallPrompt = null; wrap.hidden = true; } - }); - } else if (isIOS) { - wrap.hidden = false; - btn.addEventListener('click', () => { + } else if (isIOS) { hint.hidden = !hint.hidden; - }); - } + } + }); } /* ---------- Render: route page ---------- */