--- name: browser-extension description: Use when the project is a browser extension (Chrome, Firefox, Edge, Safari Web Extension). Triggers — manifest.json, content script, background service worker, popup, Web Store/AMO submission. --- # Browser Extension Development ## When to use - New extension scaffold from scratch (MV3) - Adding a content script, background worker, popup, options page, or side panel to an existing extension - Migrating a Manifest V2 extension to Manifest V3 - Preparing a submission for Chrome Web Store, Firefox AMO, or Edge Add-ons - Debugging cross-browser permission or messaging issues ## Workflow 1. **Classify the extension type** — decide which surfaces are needed: | Surface | File | Purpose | |---------|------|---------| | Background | `background/service-worker.js` | Long-running logic, alarms, storage sync | | Content script | `content/index.js` | Injected into host pages; DOM access | | Popup | `popup/popup.html + popup.js` | Toolbar icon click UI (ephemeral) | | Options page | `options/options.html` | Persistent settings UI | | Side panel | `sidepanel/panel.html` | Chrome 114+ persistent side panel | | DevTools panel | `devtools/devtools.html` | Page inspector integration | 2. **Write `manifest.json` (MV3 only)** — required fields: ```json { "manifest_version": 3, "name": "…", "version": "1.0.0", "description": "…", "permissions": [], "host_permissions": [], "background": { "service_worker": "background/service-worker.js" }, "action": { "default_popup": "popup/popup.html" }, "content_scripts": [], "web_accessible_resources": [] } ``` Request the minimum permission set; justify every entry in a comment block above the manifest. 3. **Implement messaging architecture** — choose ONE pattern and stick to it: - **Short-lived**: `chrome.runtime.sendMessage` / `onMessage` — fire-and-forget between popup and background. - **Long-lived**: `chrome.runtime.connect` / `Port` — streaming data from content script to background. - Never call DOM APIs from the service worker; delegate to content scripts via `chrome.tabs.sendMessage`. 4. **Handle storage correctly**: - User preferences → `chrome.storage.sync` (≤100 KB, synced across devices). - Large / sensitive data → `chrome.storage.local` (≤10 MB). - Session state (cleared on browser close) → `chrome.storage.session` (MV3 only). - Always handle `chrome.runtime.lastError` after every storage call. 5. **Content-Security-Policy** — MV3 default CSP blocks `eval` and inline scripts. Serve all scripts from extension files; never inject `