Notifications API
Notifications API
หัวข้อที่มีชื่อว่า “Notifications API”Notifications API ช่วยให้ PWA ของคุณแสดง system-level notification ได้ ต่างจาก alert box ตรงที่ notification จะปรากฏใน notification tray ของอุปกรณ์และมองเห็นได้แม้ผู้ใช้จะสลับแท็บไปแล้ว
การขอ permission
หัวข้อที่มีชื่อว่า “การขอ permission”ก่อนแสดง notification ใดๆ คุณต้องขอ permission ก่อน การเรียกนี้จะ return Promise ที่ resolve เป็น "granted", "denied" หรือ "default":
async function askPermission() { const permission = await Notification.requestPermission(); if (permission === 'granted') { console.log('Notifications allowed'); } else { console.warn('Notifications blocked or dismissed'); }}เรียกฟังก์ชันนี้เป็นการตอบสนองต่อ user gesture — การคลิกปุ่ม, การส่งฟอร์ม, การ swipe อย่าเรียกตอนโหลดหน้าเพจ
การแสดง notification จากหน้าเพจ
หัวข้อที่มีชื่อว่า “การแสดง notification จากหน้าเพจ”เมื่อได้รับ permission แล้ว คุณสามารถสร้าง notification ได้โดยตรงจาก JavaScript ของหน้าเพจ:
new Notification('Your order shipped!', { body: 'It will arrive by Thursday.', icon: '/icons/icon-192.png', badge: '/icons/badge-72.png',});วิธีนี้ใช้ได้ แต่ notification จะไม่ปรากฏถ้าไม่มีแท็บเปิดอยู่ วิธีที่ดีกว่าคือแสดง notification จาก service worker
การแสดง notification จาก service worker
หัวข้อที่มีชื่อว่า “การแสดง notification จาก service worker”ใช้ registration.showNotification() บน ServiceWorkerRegistration object โดย SW ยังคงทำงานต่อแม้ทุกแท็บจะปิดแล้ว ดังนั้น notification นี้จึงส่งได้อย่างน่าเชื่อถือ:
// main.js — page codeasync function notify(title, options) { const registration = await navigator.serviceWorker.ready; registration.showNotification(title, options);}
notify('Your order shipped!', { body: 'It will arrive by Thursday.', icon: '/icons/icon-192.png', badge: '/icons/badge-72.png', actions: [ { action: 'view', title: 'View order' }, { action: 'dismiss', title: 'Dismiss' }, ], data: { orderId: 'ORD-42' },});ตัวเลือก notification
หัวข้อที่มีชื่อว่า “ตัวเลือก notification”| ตัวเลือก | ประเภท | วัตถุประสงค์ |
|---|---|---|
body | string | ข้อความรองด้านล่างชื่อเรื่อง |
icon | string (URL) | รูปภาพขนาดใหญ่ข้าง notification |
badge | string (URL) | icon ขาวดำขนาดเล็กสำหรับ status bar |
image | string (URL) | รูปภาพ inline ขนาดใหญ่ |
actions | array | ปุ่มที่ผู้ใช้สามารถกดได้โดยไม่ต้องเปิดแอป |
data | any | ข้อมูลส่วนตัวที่ส่งไปยัง notificationclick handler |
tag | string | แทนที่ notification ที่มีอยู่ที่มี tag เดียวกัน |
renotify | boolean | แจ้งเตือนผู้ใช้อีกครั้งแม้จะแทนที่ notification ที่มี tag แล้ว |
requireInteraction | boolean | ทำให้ notification ยังคงมองเห็นได้จนกว่าผู้ใช้จะโต้ตอบ |
silent | boolean | ปิดเสียงและการสั่น |
การจัดการ notificationclick
หัวข้อที่มีชื่อว่า “การจัดการ notificationclick”event notificationclick จะเกิดขึ้นใน service worker เมื่อผู้ใช้แตะ notification หรือปุ่ม action:
// sw.js — service workerself.addEventListener('notificationclick', (event) => { event.notification.close();
if (event.action === 'view') { // Open or focus the app event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => { if (clientList.length > 0) { return clientList[0].focus(); } return clients.openWindow('/orders/' + event.notification.data.orderId); }) ); }});อย่าลืมเรียก event.notification.close() เสมอ — บน Android notification จะยังคงเปิดอยู่จนกว่าจะปิดอย่างชัดเจน
ลองใช้งานจริง
หัวข้อที่มีชื่อว่า “ลองใช้งานจริง”demo ด้านล่างแสดง local notification จาก service worker กด “Grant permission” เมื่อได้รับการแจ้ง จากนั้นกด “Notify me”
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| ขอ permission แบบ contextual (หลัง user engage แล้ว) | permission grant rate สูงกว่า ผู้ใช้เข้าใจเหตุผลก่อนตัดสินใจ | ต้องออกแบบ trigger point ที่เหมาะสม เพิ่มงานออกแบบ UX |
| ขอ permission ทันทีตอนโหลดหน้าแรก | เขียนโค้ดง่ายที่สุด | permission block rate สูงมาก ผู้ใช้กด deny เพราะยังไม่เห็นคุณค่าของแอป |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- ขอ Notification permission ทันทีตอนหน้าเว็บโหลด ทำให้ผู้ใช้ส่วนใหญ่กด block ก่อนจะรู้ด้วยซ้ำว่าแอปทำอะไร
- ไม่ handle กรณี permission ถูก “denied” ถาวร ทำให้โค้ดพยายามขอซ้ำไปเรื่อยๆ โดยไม่มีทาง recover
- แสดง notification โดยไม่ใส่ icon/tag ที่เหมาะสม ทำให้ notification เดียวกันซ้อนกันหลายอันแทนที่จะ replace อันเดิม
💡 ตัวอย่างจากของจริง
Facebook — ขอ permission เฉพาะหลังผู้ใช้ทำ action ที่เกี่ยวข้อง (เช่นส่งข้อความ) แทนที่จะขอตั้งแต่แรกเข้า
สายการบินต่างๆ — ใช้ Notifications API แจ้งเตือนเวลา check-in โดยขอ permission ตอนผู้ใช้กำลังจองตั๋วที่เป็นจังหวะที่สมเหตุสมผลที่สุด