ข้ามไปยังเนื้อหา

Install Prompt

เมื่อ browser ตัดสินใจว่า PWA ของคุณสามารถติดตั้งได้ (manifest ที่ถูกต้อง + service worker ที่ลงทะเบียน + HTTPS) จะยิง event beforeinstallprompt บน window โดยค่าเริ่มต้น browser จะแสดง install badge หรือ prompt ของตัวเองทันที — แต่คุณสามารถดักจับ event นั้น ซ่อน UI เริ่มต้น และแสดงปุ่มติดตั้งของคุณเองในเวลาที่เหมาะสม

let deferredPrompt = null;
window.addEventListener('beforeinstallprompt', (event) => {
// ป้องกันเบราว์เซอร์แสดง mini-infobar ของตัวเอง
event.preventDefault();
// เก็บ event เพื่อเรียกใช้ในภายหลัง
deferredPrompt = event;
// แสดงปุ่มติดตั้งของคุณเอง
document.getElementById('install-btn').hidden = false;
});

คุณต้องเรียก deferredPrompt.prompt() จากภายใน handler ที่เริ่มต้นโดยผู้ใช้ (การคลิก) การเรียกนอก user gesture จะทำให้เกิด error

document.getElementById('install-btn').addEventListener('click', async () => {
if (!deferredPrompt) return;
// แสดง install dialog ของเบราว์เซอร์
deferredPrompt.prompt();
// รอการเลือกของผู้ใช้
const { outcome } = await deferredPrompt.userChoice;
console.log('User choice:', outcome); // 'accepted' หรือ 'dismissed'
deferredPrompt = null;
document.getElementById('install-btn').hidden = true;
});

ขั้นตอนที่ 3 — ตอบสนองต่อการติดตั้งที่สำเร็จ

หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 3 — ตอบสนองต่อการติดตั้งที่สำเร็จ”

event appinstalled ยิงหลังจากผู้ใช้ยืนยันการติดตั้ง:

window.addEventListener('appinstalled', () => {
console.log('PWA installed successfully');
deferredPrompt = null;
});

Safari บน iOS ไม่ ยิง beforeinstallprompt ไม่มีวิธีการเรียก install dialog แบบ programmatic ทางเลือกเดียวคือแสดง banner แนะนำที่แนะนำผู้ใช้ให้ทำด้วยตนเอง:

  1. แตะปุ่ม Share ใน Safari
  2. เลื่อนลงแล้วแตะ Add to Home Screen

ตรวจสอบ iOS เพื่อแสดงคำแนะนำที่ถูกต้อง:

const isIos = /iphone|ipad|ipod/i.test(navigator.userAgent);
const isInStandaloneMode = window.matchMedia('(display-mode: standalone)').matches;
if (isIos && !isInStandaloneMode) {
document.getElementById('ios-hint').hidden = false;
}

playground ด้านล่างเชื่อมต่อ install-button flow แบบครบถ้วน เนื่องจาก StackBlitz ทำงานภายใน iframe event beforeinstallprompt จะไม่ยิง — แต่คุณสามารถตรวจสอบโค้ดทั้งหมดและรันบน domain จริงเพื่อทดสอบ

Runs a real service worker + manifest in your browser.
ตัวเลือกBenefitCost
ดักจับ beforeinstallprompt แล้วแสดงปุ่มติดตั้งเองควบคุม timing และ UI ได้เต็มที่ ไม่รบกวนผู้ใช้ตอนที่ไม่พร้อมต้อง handle state และ event lifecycle เอง เพิ่ม complexity ของโค้ด
ปล่อยให้ browser แสดง install UI ของตัวเอง (default)ไม่ต้องเขียนโค้ดเพิ่ม ได้ UI มาตรฐานทันทีควบคุม timing ไม่ได้ อาจโผล่มาตอนที่ผู้ใช้ยังไม่พร้อมตัดสินใจ
  • เรียก prompt() นอก user gesture handler (เช่นใน useEffect ตอน mount) ทำให้ browser โยน error และปฏิเสธคำขอ
  • ไม่เก็บ deferredPrompt ไว้ตั้งแต่ event แรก ทำให้พลาดโอกาสแสดงปุ่มติดตั้งไปเลยหากไม่ได้ดักจับทัน
  • ลืมว่า iOS Safari ไม่ยิง beforeinstallprompt เลย แล้วออกแบบ UI ติดตั้งที่ใช้ไม่ได้กับผู้ใช้ iOS

💡 ตัวอย่างจากของจริง

Pinterest — แสดงปุ่มติดตั้งของตัวเองหลังจากผู้ใช้มี engagement ระดับหนึ่งแล้ว แทนที่จะโชว์ตั้งแต่หน้าแรก ทำให้ conversion สูงขึ้น

Starbucks — ดักจับ beforeinstallprompt แล้วผูกกับปุ่ม “Add to Home Screen” ที่ออกแบบเข้ากับ branding ของแอปเอง

ต้องเรียกอะไรบน event beforeinstallprompt เพื่อระงับ install UI เริ่มต้นของ browser?
ต้องเรียก deferredPrompt.prompt() จากที่ไหน?
event ใดที่ยิงหลังผู้ใช้ติดตั้ง PWA สำเร็จ?
ผู้ใช้ iOS ต้องติดตั้ง PWA อย่างไรเมื่อ beforeinstallprompt ไม่พร้อมใช้งาน?