Signatur
Beschreibung
Das Ereignis contentdelete gehört zur Content Index API und wird im ServiceWorkerGlobalScope ausgelöst, wenn ein zuvor mit registration.index.add() registrierter Offline-Inhalt vom User Agent aus dem Index entfernt wird. Das passiert typischerweise, wenn der Nutzer den Eintrag in der Browser-Oberfläche löscht, etwa in Chrome für Android unter „Downloads“ → „Artikel für dich“ bzw. „Offline-Inhalte“.
Der Handler bekommt ein ContentIndexEvent, dessen Eigenschaft id die ID des gelöschten Eintrags enthält. Damit räumst du die zugehörigen Daten auf, also Einträge in der Cache Storage API, Datensätze in IndexedDB oder Bilder, die nur für diesen Inhalt heruntergeladen wurden. So bleibt der Offline-Speicher deiner App stimmig mit dem, was der Nutzer im Browser sieht.
Du kannst den Handler mit self.addEventListener("contentdelete", …) oder über die Eigenschaft self.oncontentdelete registrieren. Da das Ereignis von ExtendableEvent erbt, solltest du asynchrone Aufräumarbeiten in event.waitUntil() verpacken. Sonst kann der Browser den Service Worker beenden, bevor die Arbeiten fertig sind.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, hier immer "contentdelete". |
|
| $listener Pflicht | (event: ContentIndexEvent) => void | Handler-Funktion. Sie bekommt ein ContentIndexEvent, dessen Eigenschaft event.id (string) den gelöschten Eintrag nennt. |
|
| $event.id Pflicht | string | Nur lesbar. Die ID, die beim Aufruf von registration.index.add({ id, … }) vergeben wurde. |
|
| $event.waitUntil(promise) | (promise: Promise<any>) => void | Geerbt von ExtendableEvent. Hält den Service Worker am Leben, bis das übergebene Promise erfüllt ist. |
Rückgabewert
event.waitUntil().Beispiele
Gecachten Artikel beim Löschen durch den Nutzer entfernen (addEventListener)
// sw.js
self.addEventListener('contentdelete', (event) => {
console.log('Vom Nutzer gelöscht:', event.id);
event.waitUntil((async () => {
const cache = await caches.open('offline-articles');
// IDs wurden beim Hinzufügen als "article-<slug>" vergeben
const slug = event.id.replace('article-', '');
await cache.delete(`/articles/${slug}`);
await cache.delete(`/images/${slug}.webp`);
})());
});
Handler über die Eigenschaft oncontentdelete setzen
// sw.js – Alternative zur addEventListener-Variante
self.oncontentdelete = (event) => {
event.waitUntil(
caches.open('podcasts').then((cache) => cache.delete(`/episodes/${event.id}.mp3`))
);
};
// Handler später wieder entfernen
// self.oncontentdelete = null;
Gegenstück auf der Seite: Inhalt in den Index aufnehmen
// main.js – läuft im Fenster, nicht im Service Worker
const saveOffline = async (slug, title) => {
const registration = await navigator.serviceWorker.ready;
if (!('index' in registration)) {
console.warn('Content Index API wird nicht unterstützt');
return;
}
const cache = await caches.open('offline-articles');
await cache.add(`/articles/${slug}`);
await registration.index.add({
id: `article-${slug}`,
title,
description: 'Offline gespeicherter Artikel',
category: 'article',
url: `/articles/${slug}`,
icons: [{ src: `/images/${slug}-icon.png`, sizes: '96x96', type: 'image/png' }]
});
console.log('Gespeichert:', await registration.index.getAll());
};
saveOffline('service-worker-grundlagen', 'Service Worker – Grundlagen');
IndexedDB-Eintrag passend zur gelöschten ID entfernen
// sw.js
const openDb = () => new Promise((resolve, reject) => {
const req = indexedDB.open('offline-db', 1);
req.onupgradeneeded = () => req.result.createObjectStore('articles', { keyPath: 'id' });
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
self.addEventListener('contentdelete', (event) => {
event.waitUntil((async () => {
const db = await openDb();
await new Promise((resolve, reject) => {
const tx = db.transaction('articles', 'readwrite');
tx.objectStore('articles').delete(event.id);
tx.oncomplete = resolve;
tx.onerror = () => reject(tx.error);
});
})());
});
// Wichtig · Fallstricke
- Experimentell: Die Content Index API gibt es nur in Chromium-Browsern (Chrome/Edge 84+). Eine sichtbare Oberfläche dafür bietet praktisch nur Chrome für Android. Firefox und Safari unterstützen sie nicht. Prüfe deshalb vorher mit
'index' in registration, ob die API vorhanden ist. - Nur bei Löschung durch den User Agent: Das Ereignis wird nicht ausgelöst, wenn deine eigene Seite
registration.index.delete(id)aufruft. In diesem Fall musst du die Caches selbst direkt aufräumen. - Das Ereignis gibt es nur im Service-Worker-Kontext und nur in einem sicheren Kontext (HTTPS oder localhost), nicht im
window. - Verwende
event.waitUntil()für asynchrone Aufräumarbeiten. Sonst kann der Service Worker mitten im Löschvorgang beendet werden. - Nimm nur Inhalte in den Index auf, die wirklich offline verfügbar sind. Chrome prüft das und kann Einträge verwerfen, deren
urloffline nicht lädt.