Files
pictureFrame-webApp/public/build/index.html
T
football2801 00121aaec9
CI / test (push) Has been cancelled
feat(pwa): installable app — manifest + SW + Settings install button
The captive-portal Step-2 QR opens pictureframe.edholm.me in Safari,
which is the perfect moment to also offer "pin this to your home
screen" so the recipient gets one-tap access without typing the URL
again. Two pieces:

* Service worker at /sw.js (document root, scope "/"). Minimal —
  install/activate calls skipWaiting + clients.claim, fetch is
  passthrough. Real offline caching is intentionally out of scope;
  we only need the SW to exist so Chrome's PWA-install heuristic
  fires.

* Settings → Install app section, hidden when display-mode standalone.
  Android Chrome path: native beforeinstallprompt button.
  iOS Safari (and any other non-prompt browser): button opens a
  modal with step-by-step Share → Add to Home Screen instructions.

usePwaInstall composable handles the singleton lifecycle —
beforeinstallprompt fires once per page load and may fire before the
user navigates to Settings, so we register on module import and stash
the event for later.

Tests cover: install button rendered when not standalone, modal opens
on click without a native prompt, modal close button works.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 13:49:12 -04:00

25 lines
1.0 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>pictureFrame</title>
<link rel="icon" type="image/svg+xml" href="/build/favicon.svg" />
<link rel="manifest" href="/build/manifest.webmanifest" />
<link rel="apple-touch-icon" href="/build/icons/apple-touch-icon.png" />
<meta name="theme-color" content="#fdf6ee" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="pictureFrame" />
<script type="module" crossorigin src="/build/assets/index-BO5caB_f.js"></script>
<link rel="modulepreload" crossorigin href="/build/assets/_plugin-vue_export-helper-eepT72yB.js">
<link rel="stylesheet" crossorigin href="/build/assets/index-BlLBHR1q.css">
</head>
<body>
<div id="app"></div>
</body>
</html>