Signatur
Beschreibung
showNotification() erzeugt eine Benachrichtigung, die an die Service-Worker-Registrierung gebunden ist und nicht an ein einzelnes Dokument. Deshalb ist sie der richtige Weg für Benachrichtigungen, die nach einem push-Ereignis angezeigt werden sollen. In diesem Fall ist oft kein Tab der Anwendung geöffnet. Anders als beim Konstruktor new Notification() können Sie hier Aktionsschaltflächen (actions) verwenden. Klicks darauf behandeln Sie im Service Worker über das Ereignis notificationclick.
Sie können die Methode an zwei Stellen aufrufen: im Service Worker selbst über self.registration.showNotification() oder von einer Seite aus über navigator.serviceWorker.ready, das die Registrierung liefert. In beiden Fällen muss der Nutzer vorher mit Notification.requestPermission() zugestimmt haben (Notification.permission === "granted"). Sonst wird das zurückgegebene Promise mit einem TypeError abgelehnt.
Mit der Option tag fassen Sie Benachrichtigungen zusammen. Eine neue Benachrichtigung mit demselben Tag ersetzt die alte, statt sich darunter zu stapeln. Mit renotify: true wird der Nutzer beim Ersetzen trotzdem erneut hingewiesen. Über data hängen Sie beliebige strukturiert klonbare Daten an, zum Beispiel eine Ziel-URL. Diese können Sie später im Klick-Handler über event.notification.data wieder auslesen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $title Pflicht | string | Titel der Benachrichtigung, meist fett oben angezeigt. | |
| $options | Object | {} | Optionale Einstellungen:
|
Rückgabewert
TypeError abgelehnt, wenn die Berechtigung fehlt oder die Optionen ungültig sind, etwa renotify ohne tag oder actions bei einer Benachrichtigung ohne Service Worker. Das Promise liefert kein Notification-Objekt. Dafür gibt es getNotifications().Beispiele
Von der Seite aus: Berechtigung anfragen und Benachrichtigung zeigen
const notifyUser = async () => {
if (!('serviceWorker' in navigator) || !('Notification' in window)) {
console.log('Benachrichtigungen werden nicht unterstützt');
return;
}
// Nur als Reaktion auf eine Nutzeraktion (z. B. Klick) aufrufen
const permission = await Notification.requestPermission();
if (permission !== 'granted') {
console.log('Berechtigung verweigert');
return;
}
const registration = await navigator.serviceWorker.ready;
await registration.showNotification('Download abgeschlossen', {
body: 'bericht-2024.pdf wurde gespeichert.',
icon: '/icons/icon-192.png',
tag: 'download-status'
});
console.log('Benachrichtigung angezeigt');
};
document.querySelector('#notify').addEventListener('click', notifyUser);
Im Service Worker: Push-Nachricht als Benachrichtigung anzeigen
// sw.js
self.addEventListener('push', (event) => {
const payload = event.data?.json() ?? { title: 'Neue Nachricht', body: '' };
// waitUntil hält den Service Worker aktiv, bis die Benachrichtigung steht
event.waitUntil(
self.registration.showNotification(payload.title, {
body: payload.body,
icon: '/icons/icon-192.png',
badge: '/icons/badge-72.png',
tag: `chat-${payload.chatId}`,
renotify: true,
data: { url: `/chat/${payload.chatId}` },
actions: [
{ action: 'open', title: 'Öffnen' },
{ action: 'mute', title: 'Stummschalten' }
]
})
);
});
Klicks auf Benachrichtigung und Aktionen verarbeiten
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
if (event.action === 'mute') {
// z. B. Einstellung an den Server melden
event.waitUntil(fetch('/api/mute', { method: 'POST' }));
return;
}
const targetUrl = event.notification.data?.url ?? '/';
event.waitUntil((async () => {
const windows = await clients.matchAll({ type: 'window', includeUncontrolled: true });
const existing = windows.find((c) => new URL(c.url).pathname === targetUrl);
if (existing) return existing.focus();
return clients.openWindow(targetUrl);
})());
});
Angezeigte Benachrichtigungen abfragen und schließen
const clearChatNotifications = async (chatId) => {
const registration = await navigator.serviceWorker.ready;
const notifications = await registration.getNotifications({ tag: `chat-${chatId}` });
notifications.forEach((n) => n.close());
console.log(`${notifications.length} Benachrichtigung(en) geschlossen`);
};
clearChatNotifications(42);
// Wichtig · Fallstricke
- Berechtigung zuerst: Ohne
Notification.permission === "granted"wird das Promise mit einemTypeErrorabgelehnt. Rufen SierequestPermission()nur als Reaktion auf eine Nutzeraktion auf. Viele Browser blockieren oder verstecken Anfragen, die direkt beim Laden der Seite kommen. - Sicherer Kontext: Die Methode funktioniert nur über HTTPS (oder
localhost) und nur, wenn der Service Worker aktiv ist. Deshalb sollten Sie von der Seite ausnavigator.serviceWorker.readyverwenden stattgetRegistration(). - Push-Ereignis: Chrome verlangt, dass jede Push-Nachricht zu einer sichtbaren Benachrichtigung führt (
userVisibleOnly: true). Übergeben Sie das Promise immer anevent.waitUntil(). Sonst beendet der Browser den Service Worker womöglich zu früh. - Plattformunterschiede: Das Betriebssystem ignoriert oder kürzt Optionen wie
image,actions,vibrate,badgeundrequireInteractionje nach Plattform. Die Zahl der Aktionen ist durchNotification.maxActionsbegrenzt, meist auf 2. Firefox unterstütztactionsnur teilweise. Unter iOS/iPadOS funktioniert die Methode erst ab 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. renotify: trueohnetagundsilent: truezusammen mitvibratelösen einenTypeErroraus.- Sicherheit: Titel und Text werden als Klartext angezeigt, nicht als HTML. Prüfen Sie trotzdem Ziel-URLs aus
data, bevor Sie sie mitclients.openWindow()öffnen. So verhindern Sie Weiterleitungen auf fremde Seiten, die über manipulierte Push-Inhalte eingeschleust werden (Open Redirect).