Browser-Extension-Entwicklung mit Claude
AI generated
Claude
>_
Claude AI · Browser-Extensions · Manifest V3
Browser-Extension-Entwicklung mit Claude
Manifest-V3-Struktur, Berechtigungsmodell und Store-Review-Anforderungen von Anfang an mitdenken

Seit der verpflichtenden Umstellung auf Manifest V3 hat sich die Architektur von Browser-Extensions grundlegend verändert: Persistente Hintergrundseiten sind Vergangenheit, an ihre Stelle tritt ein Service Worker, der jederzeit beendet und neu gestartet werden kann. Wer eine eigene Extension entwickelt, muss dieses Lebenszyklus-Modell von Beginn an mitdenken, statt es nachträglich zu reparieren. Dieser Artikel zeigt, wie Claude beim Entwurf von Manifest-Struktur, Berechtigungen, Kommunikation zwischen den Komponenten und der Vorbereitung auf Store-Reviews hilft.

13 Min. Lesezeit Manifest V3 Browser-Extensions Chrome Web Store Firefox Add-ons

1. Warum Manifest V3 die Architektur grundlegend verändert

Unter Manifest V2 liefen Hintergrundskripte in einer dauerhaft geöffneten, langlebigen Hintergrundseite, in der sich globaler Zustand einfach über gewöhnliche JavaScript-Variablen halten ließ, solange der Browser lief. Manifest V3 ersetzt dieses Modell durch einen Service Worker, der aus Sicherheits- und Ressourcengründen vom Browser jederzeit beendet werden kann, sobald er einige Sekunden inaktiv war, und bei der nächsten relevanten Aktion neu gestartet wird, allerdings ohne jeden zuvor gehaltenen In-Memory-Zustand.

Dieser Wechsel ist kein rein technisches Detail, sondern verlangt ein grundlegend anderes Architekturdenken: Jeder Zustand, der über einen einzelnen Ereignis-Handler hinaus Bestand haben soll, muss explizit in chrome.storage persistiert werden, statt in einer Variablen zu leben, die stillschweigend verschwindet, sobald der Service Worker terminiert wird. Claude eignet sich gut, um bestehenden Manifest-V2-Code systematisch nach genau solchen Stellen zu durchsuchen, an denen implizit von einem dauerhaft laufenden Hintergrundprozess ausgegangen wird.

2. Manifest-Struktur und Berechtigungsmodell durchdenken lassen

Die manifest.json legt nicht nur technische Einstiegspunkte fest, sondern kommuniziert dem Nutzer beim Installationsdialog auch, welche Berechtigungen die Extension anfordert, was direkten Einfluss auf die Installationsbereitschaft hat. Eine Extension, die pauschal Zugriff auf alle Websites über <all_urls> anfordert, wirkt auf viele Nutzer und auch auf Store-Reviewer deutlich verdächtiger als eine, die gezielt nur die tatsächlich benötigten Domains über host_permissions auflistet.

Claude lässt sich gut nutzen, um aus der geplanten Funktionalität die minimal nötigen Berechtigungen abzuleiten, statt aus Bequemlichkeit von Anfang an breite Berechtigungen anzufordern. Besonders bei optionalen Funktionen lohnt sich der Blick auf optional_permissions, die erst zur Laufzeit bei tatsächlicher Nutzung angefragt werden, statt bereits bei der Installation, was sowohl die Nutzerakzeptanz erhöht als auch das Prüfungsrisiko im Store-Review senkt.


{
  "manifest_version": 3,
  "name": "Link Preview Helper",
  "version": "1.0.0",
  "permissions": ["storage", "activeTab"],
  "optional_permissions": ["tabs"],
  "host_permissions": [
    "https://api.example.com/*"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["https://*.example.com/*"],
      "js": ["content.js"]
    }
  ],
  "action": {
    "default_popup": "popup.html"
  }
}

3. Content-Script vs. Background-Service-Worker: Zuständigkeiten trennen

Content-Scripts laufen im Kontext der besuchten Webseite und haben direkten Zugriff auf deren DOM, unterliegen dabei aber denselben Content-Security-Policy-Einschränkungen wie die Seite selbst und können bestimmte browserweite APIs, etwa für Cross-Origin-Requests, nicht direkt nutzen. Der Service Worker läuft dagegen isoliert von jeder einzelnen Webseite, hat Zugriff auf die volle Extension-API, kann aber nicht direkt auf das DOM einer Seite zugreifen.

Diese Trennung erzwingt eine klare Architekturentscheidung, welche Logik wohin gehört: DOM-Manipulation und das Auslesen von Seiteninhalten gehören ins Content-Script, während API-Aufrufe zu externen Diensten, das Verwalten von persistentem Zustand und die Koordination zwischen mehreren Tabs im Service Worker stattfinden sollten. Claude lässt sich gut bitten, eine geplante Funktionalität entlang dieser Grenze aufzuteilen und dabei zu prüfen, ob eine geplante Operation überhaupt im jeweils vorgesehenen Kontext technisch möglich ist.

4. Kommunikation zwischen Content-Script und Service-Worker gestalten

Da Content-Script und Service Worker in getrennten Prozessen laufen, kommunizieren sie ausschließlich über asynchrone Nachrichten statt über direkte Funktionsaufrufe, was ein anderes mentales Modell verlangt als klassische synchrone Funktionsaufrufe innerhalb derselben Ausführungsumgebung. Die chrome.runtime.sendMessage-API liefert dabei keine Garantie, dass eine Nachricht tatsächlich zugestellt wird, etwa wenn der Service Worker gerade in dem Moment terminiert wurde, in dem die Nachricht ankommt.

Claude kann helfen, ein robustes Nachrichtenprotokoll zu entwerfen, das explizite Antwortbestätigungen und Zeitüberschreitungen einplant, statt stillschweigend von einer zuverlässigen Zustellung auszugehen. Für Fälle, in denen wiederholt Nachrichten über einen längeren Zeitraum ausgetauscht werden, etwa bei einem Live-Update während des Scrollens einer Seite, empfiehlt sich der Wechsel zu einem Port-basierten, langlebigen Verbindungskanal statt einzelner Einzelnachrichten.


// content.js: Nachricht an den Service Worker senden, mit Fehlerbehandlung
async function reportPageData(data) {
  try {
    const response = await chrome.runtime.sendMessage({
      type: 'PAGE_DATA_COLLECTED',
      payload: data,
    });
    if (!response?.ok) {
      console.warn('Service Worker hat die Nachricht nicht bestätigt');
    }
  } catch (err) {
    // Service Worker war inaktiv oder wurde gerade beendet
    console.error('Nachricht konnte nicht zugestellt werden', err);
  }
}

// background.js: auf Nachrichten reagieren und explizit antworten
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'PAGE_DATA_COLLECTED') {
    persistPageData(message.payload).then(() => sendResponse({ ok: true }));
    return true; // hält den Kanal offen für die asynchrone Antwort
  }
});

5. Speicher und Zustand: chrome.storage statt globaler Variablen

Da der Service Worker jederzeit terminiert werden kann, ist jede globale Variable, die Zustand über mehrere Ereignisse hinweg halten soll, ein latenter Bug. Die chrome.storage-API bietet dafür den vorgesehenen, persistenten Ersatz, wobei chrome.storage.local für größere, gerätegebundene Daten geeignet ist, während chrome.storage.sync kleinere Einstellungen automatisch über die Geräte eines angemeldeten Nutzers hinweg synchronisiert, dafür aber deutlich engeren Speicherquoten unterliegt.

Claude lässt sich gezielt bitten, bestehenden Code auf implizite Annahmen über dauerhaften In-Memory-Zustand zu prüfen, etwa einen Zähler, der bei jedem Seitenaufruf erhöht wird und ohne Persistierung bei jeder Terminierung des Service Workers stillschweigend auf null zurückfällt. Solche Fehler fallen im lokalen Testbetrieb oft nicht auf, weil der Service Worker während aktiver Entwicklung selten lange genug inaktiv bleibt, um beendet zu werden, zeigen sich im echten Nutzungsalltag aber zuverlässig.

6. Berechtigungen minimal halten nach dem Least-Privilege-Prinzip

Jede angeforderte Berechtigung erhöht nicht nur die Skepsis von Nutzern beim Installationsdialog, sondern auch die Prüftiefe im Store-Review-Prozess, weil bestimmte, als sensibel eingestufte Berechtigungen automatisch eine manuelle, oft mehrwöchige Prüfung nach sich ziehen, statt einer schnelleren, größtenteils automatisierten Freigabe. Berechtigungen wie webRequest mit Blocking-Fähigkeiten oder umfassende Host-Berechtigungen über alle Websites gehören zu den am kritischsten geprüften Kategorien.

Claude eignet sich gut, um für jede im Code tatsächlich genutzte API-Funktion zu prüfen, welche minimale Berechtigung dafür wirklich erforderlich ist, und dabei aufzudecken, wenn eine im Manifest deklarierte Berechtigung im Code gar nicht mehr genutzt wird, ein häufiges Überbleibsel aus früheren Entwicklungsphasen, das bei jedem Store-Review unnötig Verdacht erregt.

7. Store-Review-Anforderungen des Chrome Web Store beachten

Der Chrome Web Store verlangt unter anderem eine klare Datenschutzerklärung, die exakt beschreibt, welche Nutzerdaten erfasst und wofür sie verwendet werden, sowie die Einhaltung der Single-Purpose-Policy, nach der eine Extension einen klar umrissenen, in der Beschreibung nachvollziehbaren Hauptzweck erfüllen muss, statt eine unübersichtliche Ansammlung unzusammenhängender Funktionen zu bündeln. Verstöße gegen diese Richtlinie sind einer der häufigsten Ablehnungsgründe im Review-Prozess.

Claude lässt sich gut nutzen, um die eigene Store-Beschreibung und Datenschutzerklärung gegen den tatsächlichen Funktionsumfang und die tatsächlich angeforderten Berechtigungen abzugleichen, denn Diskrepanzen zwischen behauptetem und tatsächlichem Verhalten fallen im automatisierten Code-Scan des Reviews zuverlässig auf und führen zu Rückweisungen, die den gesamten Review-Zyklus, der mehrere Tage bis Wochen dauern kann, erneut in Gang setzen.

8. Firefox-Add-ons-Besonderheiten: WebExtensions-Unterschiede

Firefox unterstützt zwar denselben WebExtensions-Standard wie Chrome, implementiert einzelne APIs aber mit abweichendem Verhalten, etwa promise-basierte APIs über den browser-Namensraum anstelle des callback-basierten chrome-Namensraums, sowie teils unterschiedliche Manifest-V3-Unterstützung für bestimmte Service-Worker-Funktionen. Eine Extension, die ausschließlich gegen die Chrome-API entwickelt und getestet wurde, läuft in Firefox deshalb nicht automatisch fehlerfrei.

Claude kann helfen, ein passendes Kompatibilitäts-Polyfill einzusetzen und gezielt jene Codestellen zu identifizieren, die auf Chrome-spezifisches Verhalten angewiesen sind, etwa bestimmte Timing-Annahmen zur Service-Worker-Terminierung, die sich zwischen den Browsern unterscheiden. Für eine Extension, die in beiden Stores veröffentlicht werden soll, lohnt sich früh im Entwurf eine gemeinsame, browserneutrale Abstraktionsschicht statt zweier komplett getrennter Codebasen.


// Browserneutrale Abstraktion statt direkter chrome.*-Aufrufe
const api = typeof browser !== 'undefined' ? browser : chrome;

async function getStoredSettings() {
  // In Firefox promise-basiert, in Chrome via Polyfill ebenfalls promise-basiert
  return api.storage.local.get('settings');
}

9. Manifest-V3-Komponenten im Überblick

Die folgende Tabelle fasst die zentralen Komponenten einer Manifest-V3-Extension mit ihrer jeweiligen Lebensdauer und typischen Fallstricken zusammen.

Komponente Aufgabe Lebensdauer Typischer Fallstrick
Background Service Worker Zentrale Logik, API-Aufrufe, Koordination Kurzlebig, jederzeit terminierbar Zustand in globalen Variablen statt chrome.storage
Content Script DOM-Zugriff auf der besuchten Seite Lebt mit dem jeweiligen Tab Unterliegt der CSP der besuchten Seite
Popup UI beim Klick auf das Extension-Icon Nur während Popup geöffnet ist Zustand geht beim Schließen verloren
Options Page Konfigurationsoberfläche der Extension Nur während Seite geöffnet ist Einstellungen ohne chrome.storage.sync nicht geräteübergreifend
DevTools Page Erweiterung der Browser-Entwicklertools Nur während DevTools geöffnet sind Eingeschränkter API-Zugriff im Vergleich zum Service Worker

Mironsoft

KI-gestützte Entwicklung, Agenten-Workflows und Team-Prozesse

Claude oder andere KI-Tools im Team einsetzen, aber ohne klaren Workflow?

Wir richten KI-gestützte Entwicklungs-Workflows für Teams ein, von CLAUDE.md-Konventionen über Subagenten-Strategien bis zu Code-Review-Prozessen, die menschliche Kontrolle und KI-Tempo verbinden.

Workflow-Setup

CLAUDE.md, Projektkonventionen und Tool-Berechtigungen für das Team sauber einrichten.

Agenten-Strategie

Subagenten- und Automatisierungs-Workflows für wiederkehrende Entwicklungsaufgaben aufbauen.

Team-Onboarding

Entwickler im produktiven, sicheren Umgang mit KI-Coding-Assistenten schulen.

10. Zusammenfassung

Browser-Extension-Entwicklung mit Claude: Das Wichtigste auf einen Blick

Kernidee

Manifest V3 ersetzt dauerhafte Hintergrundseiten durch einen jederzeit terminierbaren Service Worker, was Zustand explizit persistieren muss.

Wichtigstes Prinzip

Berechtigungen minimal halten, denn jede zusätzliche Berechtigung erhöht Nutzer-Skepsis und Review-Prüftiefe.

Größter Architekturschnitt

Klare Trennung zwischen Content-Script für DOM-Zugriff und Service Worker für API-Logik und Koordination.

Store-Regel

Beschreibung, Datenschutzerklärung und angeforderte Berechtigungen müssen exakt zum tatsächlichen Verhalten passen.

11. FAQ: Browser-Extension-Entwicklung mit Claude: Das Wichtigste auf einen Blick

1Warum verändert Manifest V3 die Extension-Architektur grundlegend?
Weil der Service Worker jederzeit terminiert werden kann und dabei jeden In-Memory-Zustand verliert.
2Wo sollte persistenter Zustand in einer Manifest-V3-Extension gespeichert werden?
In chrome.storage.local oder chrome.storage.sync, nicht in globalen JavaScript-Variablen.
3Was unterscheidet Content-Script und Service Worker technisch?
Content-Scripts haben DOM-Zugriff, unterliegen aber der CSP der Seite, der Service Worker hat volle Extension-API, aber keinen DOM-Zugriff.
4Warum ist chrome.runtime.sendMessage nicht immer zuverlässig?
Weil der Service Worker genau in dem Moment terminiert sein kann, in dem eine Nachricht ankommt.
5Was besagt die Single-Purpose-Policy des Chrome Web Store?
Eine Extension muss einen klar umrissenen, in der Beschreibung nachvollziehbaren Hauptzweck erfüllen.
6Warum sollten Berechtigungen minimal gehalten werden?
Weil sie sowohl Nutzer-Skepsis als auch die Prüftiefe im Store-Review-Prozess erhöhen.
7Was ist optional_permissions im Manifest?
Berechtigungen, die erst zur Laufzeit bei tatsächlicher Nutzung angefragt werden, statt bereits bei der Installation.
8Worin unterscheiden sich Chrome- und Firefox-Extension-APIs?
Firefox nutzt einen promise-basierten browser-Namensraum, Chrome traditionell einen callback-basierten chrome-Namensraum.
9Was ist der häufigste Grund für Ablehnungen im Chrome Web Store?
Verstöße gegen die Single-Purpose-Policy sowie Diskrepanzen zwischen Datenschutzerklärung und tatsächlichem Verhalten.
10Wann lohnt sich ein Port-basierter Verbindungskanal statt einzelner Nachrichten?
Bei wiederholtem Nachrichtenaustausch über einen längeren Zeitraum, etwa bei Live-Updates während des Scrollens.