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

Badging และ Share Target

App Badging API ช่วยให้ PWA ที่ install แล้วแสดง badge เล็กๆ บน icon ใน OS taskbar, dock หรือ home screen ได้ นี่คือจุดสีเดียวกับจำนวน unread ที่คุณเห็นในแอปส่งข้อความ native

// Show a numeric badge
async function setBadge(count) {
if ('setAppBadge' in navigator) {
await navigator.setAppBadge(count);
}
}
// Show a plain dot (no number)
async function setDotBadge() {
if ('setAppBadge' in navigator) {
await navigator.setAppBadge();
}
}
// Clear the badge
async function clearBadge() {
if ('clearAppBadge' in navigator) {
await navigator.clearAppBadge();
}
}

ตรวจสอบ feature ด้วย 'setAppBadge' in navigator เสมอ — API นี้รองรับใน browser ที่ใช้ Chromium บน desktop และ Android แต่ยังไม่รองรับในทุก browser

คุณยังสามารถเรียก navigator.setAppBadge จากภายใน service worker ได้ เช่น เมื่อมี push message เข้ามา:

// sw.js — service worker
self.addEventListener('push', (event) => {
const data = event.data ? event.data.json() : {};
event.waitUntil(
Promise.all([
self.registration.showNotification(data.title || 'New message', {
body: data.body || '',
icon: '/icons/icon-192.png',
}),
navigator.setAppBadge(data.unreadCount || 1),
])
);
});
  • อัปเดต badge ทุกครั้งที่แสดง notification ไม่ใช่แค่เมื่อแอปเปิดอยู่
  • ล้าง badge ใน notificationclick handler และเมื่อผู้ใช้ดูเนื้อหาที่เกี่ยวข้อง
  • อย่าใช้ badge เพื่อนับทุก background event — ใช้เฉพาะรายการที่ผู้ใช้มองเห็นได้ (ข้อความ, งาน, การแจ้งเตือน)

Web Share Target API ช่วยให้ PWA ที่ install แล้วปรากฏใน OS share sheet เป็น destination ได้ เมื่อผู้ใช้แชร์รูปภาพจากแกลเลอรีหรือลิงก์จาก browser อื่น PWA ของคุณสามารถแสดงอยู่ร่วมกับแอป native

เพิ่ม share_target ใน manifest.webmanifest ของคุณ:

{
"name": "My App",
"share_target": {
"action": "/share",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "title",
"text": "text",
"url": "url",
"files": [{ "name": "media", "accept": ["image/*"] }]
}
}
}

เมื่อผู้ใช้แชร์ไปยัง PWA ของคุณ browser จะ navigate ไปที่ /share และ POST multipart/form-data body พร้อม fields ที่ map ไว้ใน params

// /share page script
const formData = new FormData(document.forms[0]);
const title = formData.get('title');
const text = formData.get('text');
const url = formData.get('url');
const file = formData.get('media');
console.log('Received share:', { title, text, url, file });

สำหรับ GET-based share (เฉพาะข้อความ/URL) ใช้ method: "GET" และ params จะถูก append เป็น query strings


Web Share API (navigator.share) ช่วยให้ PWA ของคุณ trigger OS share sheet เพื่อแชร์เนื้อหา จาก แอปของคุณไปยังแอปอื่น เป็นคู่ตรงข้ามของ Share Target

async function shareContent() {
if (!('share' in navigator)) {
// Fallback: copy to clipboard
await navigator.clipboard.writeText(window.location.href);
return;
}
try {
await navigator.share({
title: 'Check out this recipe',
text: 'I found this amazing recipe for sourdough bread.',
url: window.location.href,
});
console.log('Shared successfully');
} catch (err) {
if (err.name !== 'AbortError') {
console.error('Share failed:', err);
}
}
}

navigator.share ต้องเรียกจาก user gesture (คลิก, แตะ) จับ AbortError แยกต่างหาก — แค่หมายความว่าผู้ใช้ปิด share sheet

คุณยังสามารถแชร์ไฟล์ (รูปภาพ, PDF) โดยใช้ option files ตรวจสอบ support ก่อน:

async function shareFile(file) {
if (navigator.canShare && navigator.canShare({ files: [file] })) {
await navigator.share({ files: [file], title: file.name });
}
}

บทเรียนแบบ code-only: Badging API ทำงานได้โดยไม่ต้องมี server Web Share Target ต้องการให้ PWA ถูก install ก่อน (การเปลี่ยน manifest จะมีผลหลัง installation) Web Share จะ trigger native OS share sheet ซึ่งไม่สามารถ demo ใน iframe ได้ รันตัวอย่างเหล่านี้ใน PWA ที่ install จริง

ตัวเลือกBenefitCost
App Badging APIแจ้งจำนวนที่ยังไม่อ่านได้แบบ native โดยไม่รบกวนด้วย notification popupรองรับเฉพาะบาง platform (desktop Chrome/Edge, ไม่มีบน iOS)
Share Target APIรับ content ที่แชร์มาจากแอปอื่นได้เหมือน native appต้อง register ใน manifest และรองรับเฉพาะ browser ที่ implement แล้ว
  • ไม่ clearAppBadge() เมื่อผู้ใช้อ่านแล้ว ทำให้ badge ค้างเลขเก่าตลอดไปจนผู้ใช้เลิกเชื่อตัวเลขนั้น
  • ตั้ง share_target ผิด method/enctype ใน manifest ทำให้ OS ส่ง data มาแบบที่แอป parse ไม่ได้
  • ลืมว่า Badging API ไม่มีบน iOS Safari เลย แล้วออกแบบ flow ที่พึ่งพา badge เป็นทางเดียวในการแจ้งเตือน

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

Facebook Messenger PWA — ใช้ App Badging แสดงจำนวนข้อความที่ยังไม่อ่านบน icon ทันที เหมือนแอป native

Squoosh — implement Share Target ให้ผู้ใช้แชร์รูปจากแอปอื่นเข้ามาบีบอัดได้ทันทีโดยไม่ต้องเปิดเว็บแล้วอัปโหลดเอง

method ใดที่ล้าง badge ออกจาก icon ของแอป?
คุณประกาศ Web Share Target ที่ไหน?
ต้องเป็นจริงข้อใดก่อนจึงจะเรียก navigator.share() ได้?
ควร catch แล้วเพิกเฉย error ชื่อใดเมื่อผู้ใช้ปิด share sheet?