インストール

PWA を「ホーム画面に追加」させる仕組み。Android Chrome は beforeinstallprompt イベントで 独自プロンプトを出せる。iOS はユーザー手動のみ。

インストール可能になる条件

Android Chrome — beforeinstallprompt

Chrome は条件を満たすと beforeinstallprompt を発火。preventDefault してイベントを保持し、 後で prompt() を呼ぶとインストール UI が出る。

let deferredPrompt = null

window.addEventListener("beforeinstallprompt", (e) => {
  e.preventDefault()
  deferredPrompt = e
  showInstallButton()
})

document.querySelector("#install-btn").addEventListener("click", async () => {
  if (!deferredPrompt) return
  deferredPrompt.prompt()
  const { outcome } = await deferredPrompt.userChoice
  console.log(outcome)        // "accepted" or "dismissed"
  deferredPrompt = null
  hideInstallButton()
})

window.addEventListener("appinstalled", () => {
  console.log("installed")
  hideInstallButton()
})

iOS — 手動インストール

iOS Safari は beforeinstallprompt を持たない。「共有」→「ホーム画面に追加」を案内する UI を作る。

function isIOS() {
  return /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as any).MSStream
}
function isStandalone() {
  return ("standalone" in navigator && (navigator as any).standalone) ||
         window.matchMedia("(display-mode: standalone)").matches
}

if (isIOS() && !isStandalone()) {
  showIOSInstallHint()    // 「共有 → ホーム画面に追加」の案内
}

インストール済みかを判定

const isStandalone =
  window.matchMedia("(display-mode: standalone)").matches ||
  (window.navigator as any).standalone === true ||
  document.referrer.startsWith("android-app://")

if (isStandalone) {
  // PWA として起動されている
}

インストールボタンの UX

断られた時の処理

const { outcome } = await deferredPrompt.userChoice
if (outcome === "dismissed") {
  localStorage.setItem("install-dismissed-at", Date.now().toString())
}

// 次回チェック
const dismissedAt = Number(localStorage.getItem("install-dismissed-at") ?? 0)
const cooldown = 7 * 24 * 60 * 60 * 1000      // 1週間
if (Date.now() - dismissedAt < cooldown) {
  return    // 出さない
}

display-mode を使ったスタイル分岐

/* PWA として起動された時だけ */
@media (display-mode: standalone) {
  .top-bar { display: none; }    /* 戻るボタン等は不要 */
  .install-banner { display: none; }
}

App Store / Google Play への配布

WebAPK(Android)

Chrome は PWA を「ホームに追加」した時、自動でWebAPKを生成。 これは普通のアプリと同じ扱いになり、アプリ一覧・通知・設定から見える。 manifest の nameicons が確定的なら自動。

インストール後の挙動

シェルの設計(App Shell パターン)

PWA のUI 骨格を最初にキャッシュして、瞬時に表示する。中身は後から動的にロード:

  1. HTML / CSS / JS のシェル部分を precache
  2. 初回起動から白画面なしでナビ等が見える
  3. API データは Stale-While-Revalidate でゆっくり差し替え

トラブルシュート

UX チェック

✓ 初回はインストールボタン出さない
✓ 断られたら 1 週間以上出さない
✓ iOS には専用の手順説明を出す
display-mode: standalone で PWA 専用 UI
✓ App Shell をキャッシュして起動瞬時に