chrome-extension
samber/cc-skills
Подробное руководство по созданию расширений для Chrome с использованием Manifest V3. Используйте этот навык всякий раз, когда пользователь упоминает расширение Chrome, расширение браузера, manifest.json, контентный скрипт, сервис-работник (в контексте расширения), всплывающее окно, боковую панель, chrome.runtime, chrome.tabs, chrome.storage, chrome.scripting, фоновый скрипт, MV3, Manifest V3 или любой API расширения Chrome. Также запускайте этот навык, когда пользователь хочет вставлять скрипты в веб-страницы, осуществлять взаимодействие между страницей и фоновым скриптом, обходить CSP со стороны контента
...Расширить всеО chrome-extension
Подробное руководство по созданию, отладке и публикации расширений Chrome с использованием Manifest V3, структурированное в виде маршрутизационного документа. Сначала следует прочитать основной файл, чтобы понять архитектуру и ключевые моменты принятия решений, после чего для ознакомления с деталями реализации загружается только соответствующий, самостоятельный справочный файл. Справочные файлы охватывают настройку и управление версиями manifest.json, жизненный цикл сервисного рабочего и сохранение состояния, контент-скрипты и их внедрение в изолированную среду по сравнению с основной средой, уровни обмена сообщениями и RPC, элементы пользовательского интерфейса (всплывающие окна, страница настроек, боковая панель, контекстные меню, команды, уведомления, универсальный адресный ряд, панель инструментов разработчика), использование chrome.storage и квоты, обработку сетевых запросов и CSP, разрешения, ресурсы, доступные через веб, настройку сборки TypeScript, публикацию в Chrome Web Store, диаграммы потока контекстов выполнения, а также распространённые ошибки при отладке. Курс предназначен для разработчиков ИИ и требует наличия git и node; в качестве инструментов указаны средства для редактирования файлов, а также команды git, gh и npm.
В обзоре архитектуры объясняется, что расширение имеет до пяти контекстов выполнения, которые взаимодействуют посредством передачи сообщений: сервисный рабочий процесс (работает в фоновом режиме, без DOM, эфемеричен, с доступом ко всем API chrome.* API), всплывающее окно, страница настроек и боковая панель (все с полным доступом к DOM и API), а также, на самой веб-странице, скрипт контента в изолированной среде и скрипт основной среды в контексте страницы. На диаграммах показано, что скрипт контента использует общий DOM, но имеет собственную область видимости JS и доступ к chrome.runtime и chrome.storage, при этом подчиняясь CSP только для сети, тогда как скрипт основного контекста имеет полный доступ к странице, но не имеет доступа к chrome.* API и полностью подчиняется CSP. Они взаимодействуют через window.postMessage посредством общего DOM.
Схемы взаимодействия обобщены в таблицах: chrome.runtime.sendMessage для однократного запроса/ответа из любого контекста расширения в сервисный рабочий процесс (наиболее распространённый случай), chrome.tabs.sendMessage — для передачи данных из сервисного рабочего процесса в конкретную вкладку по tabId; порты chrome.runtime.connect — для двунаправленной потоковой передачи и отслеживания прогресса (включая передачу данных из сервисного рабочего процесса во всплывающее окно); а также window.postMessage — для соединения контекстов на одной странице. Поскольку сервисный рабочий процесс является кратковременным и не может отправлять данные напрямую на страницы расширений, руководство рекомендует читателям использовать порты или chrome.storage.onChanged, который срабатывает одновременно во всех контекстах, а также указывает на справочник по контекстам выполнения для более подробных диаграмм потоков и разбивки возможностей и ограничений по каждому контексту. В описании навыка явно указано, что его не следует использовать для вопросов, связанных с конкретными фреймворками.
Часто задаваемые вопросы
Какую версию манифеста расширений Chrome охватывает данное руководство?
Манифест V3 (MV3). В нём рассматриваются настройка и изменение файла manifest.json, настройка значков и управление версиями, а также более общая архитектура MV3, обмен сообщениями и процесс публикации.
Как организован этот навык?
В виде документа с маршрутизацией. Сначала вы читаете основной файл SKILL.md, чтобы ознакомиться с архитектурой и точками принятия решений, а затем загружаете только соответствующий, самостоятельный справочный файл (например, service-worker.md, content-scripts.md или messaging-rpc.md) для получения подробностей реализации.
Какие контексты выполнения имеет расширение Chrome согласно этому руководству?
До пяти контекстов, взаимодействующих посредством передачи сообщений: сервис-работник (фоновый режим), всплывающее окно, страница настроек и боковая панель в рамках процесса расширения, а также скрипт контента (изолированная среда) и скрипт основной среды на веб-странице.
Какой метод обмена сообщениями следует использовать для типичного запроса/ответа?
chrome.runtime.sendMessage из любого контекста расширения в сервис-работник, что, как отмечается в руководстве, покрывает около девяноста процентов случаев. Для отправки сообщений на конкретную вкладку используйте chrome.tabs.sendMessage, а для двунаправленной потоковой передачи — порты chrome.runtime.connect.
Каковы предварительные условия для использования этого навыка?
Он разработан для Claude Code или аналогичных ИИ-агентов по программированию и требует наличия git и node (в метаданных указаны git, node и npm). Он не предназначен для вопросов, связанных с конкретными фреймворками.
Все файлы
14файловreferences/content-scripts.md12,5КБ Просмотретьreferences/execution-contexts.md18,3КБ Просмотретьreferences/messaging-rpc.md19,4КБ Просмотретьreferences/permissions.md8,0КБ Просмотретьreferences/service-worker.md 10,9КБ Просмотр references/typescript-build.md 7,9КБ Просмотр references/debugging-mistakes.md 9,2КБ Просмотр references/manifest-v3.md 7,2КБ Просмотр references/network-csp.md 9,9КБ Просмотр references/publishing.md6,4КБ Просмотреть ссылки/storage.md9,0КБ Просмотреть ссылки/ui-surfaces.md9,7КБ Просмотреть ссылки/web-accessible-resources.md3,1КБ Просмотреть SKILL.md16,0 КБ ПросмотретьThis skill covers everything needed to build, debug, and publish Chrome extensions with MV3. It is organized as a routing document: read this file first to understand the architecture and decision points, then load the relevant reference file for implementation details.
Reference files
Read only the reference files relevant to the current task. Each file is self-contained.
| File | When to read |
|---|---|
references/manifest-v3.md | Setting up or modifying manifest.json, configuring icons, versioning |
references/service-worker.md | Background logic, lifecycle, state persistence, alarms, events |
references/content-scripts.md | Injecting code into pages, isolated/main world, dynamic injection, SPA handling, orphaning |
references/messaging-rpc.md | Communication between any contexts, typed protocols, RPC layer, async handler patterns |
references/ui-surfaces.md | Popup, options page, side panel, context menus, commands, notifications, omnibox, devtools panel |
references/storage.md | chrome.storage (local/sync/session), quotas, reactive patterns, framework hooks |
references/network-csp.md | HTTP requests from content scripts, CSP bypass relay, declarativeNetRequest, offscreen docs, CORS |
references/permissions.md | Required/optional permissions, host permissions, activeTab, runtime request flow |
references/web-accessible-resources.md | Exposing extension files to web pages, security implications |
references/typescript-build.md | TypeScript setup, project structure, build tools comparison, bundling |
references/publishing.md | Chrome Web Store submission, review process, rejection reasons, updates, privacy policy |
references/execution-contexts.md | Communication flow diagrams, per-context capabilities/limits, choosing the right messaging method |
references/debugging-mistakes.md | DevTools for extensions, testing SW termination, common gotchas, error patterns |
Architecture overview
A Chrome extension has up to 5 execution contexts that communicate via message passing:
┌──────────────────────────────────────────────────────────┐│ Extension Process ││ ┌─────────────────┐ ┌───────┐ ┌─────────┐ ┌──────┐ ││ │ Service Worker │ │ Popup │ │ Options │ │ Side │ ││ │ (background) │ │ │ │ Page │ │Panel │ ││ │ - No DOM │ │ Full │ │ Full │ │ Full │ ││ │ - Ephemeral │ │ DOM │ │ DOM │ │ DOM │ ││ │ - All chrome.* │ │ All │ │ All │ │ All │ ││ │ APIs │ │ APIs │ │ APIs │ │ APIs │ ││ └────────┬─────────┘ └───┬───┘ └────┬────┘ └──┬───┘ ││ │ chrome.runtime.sendMessage / connect │ │└───────────┼────────────────┼───────────┼──────────┼──────┘ │ │ │ │ chrome.tabs.sendMessage │ │ │ │ │ │ │┌───────────┼────────────────┼───────────┼──────────┼──────┐│ Web Page ▼ ││ ┌──────────────────┐ ┌──────────────────┐ ││ │ Content Script │ │ Main World Script │ ││ │ (isolated world) │◄──►│ (page context) │ ││ │ - Shared DOM │ │ - Shared DOM │ ││ │ - Own JS scope │ │ - Page JS scope │ ││ │ - chrome.runtime │ │ - No chrome.* API │ ││ │ - chrome.storage │ │ - Full page access│ ││ │ - Subject to CSP │ │ - Subject to CSP │ ││ │ (network only) │ │ (fully) │ ││ └──────────────────┘ └──────────────────┘ ││ ▲ window.postMessage ││ │ (through shared DOM) │└──────────────────────────────────────────────────────────┘Communication flows (labeled channels)
┌───────────────────────────────────────────────────────────────────────────┐│ Extension Process ││ ││ ┌─────────────────┐ chrome.runtime ┌───────┐ ┌─────────┐ ┌──────┐ ││ │ Service Worker │◄─.sendMessage()──│ Popup │ │ Options │ │ Side │ ││ │ (background) │◄─.connect()──────│ │ │ Page │ │Panel │ ││ │ │ └───────┘ └─────────┘ └──────┘ ││ │ - No DOM │ ┌────────────────────────────────────────────┐ ││ │ - Ephemeral 30s │ │ SW cannot push to these pages. │ ││ │ - All chrome.* │ │ Use: ports (.connect) or storage.onChanged │ ││ └────────┬─────────┘ └────────────────────────────────────────────┘ ││ │ ││ chrome.storage.onChanged ◄── fires across ALL contexts simultaneously ││ │└───────────┼──────────────────────────────────────────────────────────────┘ │ chrome.tabs.sendMessage(tabId, ...) [SW must know tabId] │┌───────────┼──────────────────────────────────────────────────────────────┐│ Web Page ▼ ││ ┌──────────────────┐ window.postMessage ┌──────────────────┐ ││ │ Content Script │◄───────────────────►│ Main World Script │ ││ │ (isolated world) │ Custom DOM events │ (page context) │ ││ │ │ │ │ ││ │ chrome.runtime ───┼── to/from SW │ No chrome.* APIs │ ││ │ chrome.storage │ │ Full page JS │ ││ │ Shared DOM │ │ Shared DOM │ ││ │ Page CSP (network)│ │ Page CSP (full) │ ││ └──────────────────┘ └──────────────────┘ │└──────────────────────────────────────────────────────────────────────────┘For detailed flow diagrams (three-layer bridge, cross-extension, storage broadcast) and a per-context breakdown of permissions, limits, and workarounds: → Read references/execution-contexts.md
Communication methods at a glance
| Method | Direction | Best for |
|---|---|---|
chrome.runtime.sendMessage | Any ext context → SW | One-shot request/response (90% of cases) |
chrome.tabs.sendMessage | SW → content script (by tabId) | Pushing data to a specific tab |
chrome.runtime.connect (Port) | Bidirectional | Streaming, progress, SW ↔ popup |
window.postMessage | Between worlds on same page | Page JS ↔ content script bridge |
chrome.storage.onChanged | Broadcast to all contexts | Settings sync, no messaging needed |
→ Full matrix with limits and edge cases: references/execution-contexts.md → Implementation patterns, typed protocols, RPC layer: references/messaging-rpc.md
Key architectural rules
Service worker is ephemeral. It terminates after 30s of inactivity. All state must be persisted to chrome.storage. All event listeners must be registered synchronously at the top level. Never use setTimeout/setInterval for anything beyond a few seconds. → Read
references/service-worker.mdContent scripts run in the page's origin. Network requests from content scripts are subject to the page's CSP and CORS. To bypass, relay through the service worker. → Read
references/network-csp.mdMessaging is the backbone. Every cross-context interaction uses chrome.runtime messaging. The #1 bug: forgetting to
return truefrom async message listeners. → Readreferences/messaging-rpc.mdPermissions determine CWS review speed. Broad host_permissions trigger manual review (weeks). activeTab + optional permissions = fast automated review. → Read
references/permissions.mdPopup is destroyed on blur. Side panel persists. Choose based on interaction duration. → Read
references/ui-surfaces.md
Decision tree: which context handles what?
"I need to run code when the user visits a page"
→ Content script. Static (manifest) for known URL patterns, dynamic (chrome.scripting) for user-triggered injection. Default to isolated world unless you need page JS access. → Read references/content-scripts.md
"I need to make an HTTP request to my API"
- From popup/options/side panel: direct fetch() works (extension origin, no CSP issues)
- From content script on a page with restrictive CSP: relay through service worker
- From service worker: direct fetch() works (requires host_permissions for the target domain) → Read
references/network-csp.md
"I need to store user settings"
- Settings that sync across devices: chrome.storage.sync (100KB limit)
- Large data or caches: chrome.storage.local (10MB, or unlimited with permission)
- Ephemeral state surviving SW restarts: chrome.storage.session → Read
references/storage.md
"I need to modify HTTP headers or block requests"
→ declarativeNetRequest (NOT webRequest, which lost blocking in MV3) → Read references/network-csp.md
"I need the page's JavaScript to talk to my extension"
→ Three-layer bridge: page (window.postMessage) → content script → service worker → Read references/messaging-rpc.md
"I need to understand what each context can and cannot do"
→ Read references/execution-contexts.md — per-context cards listing chrome.* access, DOM, network, storage, lifetime, hard limits, and practical workarounds.
"I need periodic background tasks"
→ chrome.alarms (minimum 30s interval). NOT setTimeout. → Read references/service-worker.md
"I need DOM APIs in the background" (DOMParser, Canvas, Audio)
→ Offscreen document. One per extension, only chrome.runtime available. → Read references/network-csp.md
"I need to authenticate with OAuth"
→ chrome.identity.launchWebAuthFlow() or chrome.identity.getAuthToken() (Google only) → Read references/service-worker.md (identity section)
Workflow: new extension from scratch
Define the manifest with minimum permissions. Start with
activeTab+scripting. → Readreferences/manifest-v3.mdSet up TypeScript and build tooling (or use CRXJS for Vite-based dev). → Read
references/typescript-build.mdImplement the service worker with all event listeners at the top level. → Read
references/service-worker.mdAdd content scripts if you need page interaction. → Read
references/content-scripts.mdBuild UI surfaces (popup, options, side panel) as needed. → Read
references/ui-surfaces.mdWire up messaging between all contexts. → Read
references/messaging-rpc.mdTest with DevTools, specifically test service worker termination. → Read
references/debugging-mistakes.mdPublish to Chrome Web Store. → Read
references/publishing.md
Workflow: adding a feature to an existing extension
- Identify which context the feature belongs to (see decision tree above).
- Read the relevant reference file(s) for that context.
- Check if new permissions are needed. Prefer optional_permissions for new capabilities. → Read
references/permissions.md - Update the manifest if adding new content scripts, UI surfaces, or permissions.
- Handle extension updates gracefully (content script orphaning). → Read
references/content-scripts.md(orphaning section)
Minimal manifest.json template
{ "manifest_version": 3, "name": "My Extension", "version": "1.0.0", "description": "What it does in one sentence", "permissions": ["storage", "activeTab", "scripting"], "action": { "default_popup": "popup.html", "default_icon": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" } }, "background": { "service_worker": "background.js", "type": "module" }, "icons": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" }}→ For the full manifest reference with all fields: references/manifest-v3.md
Code patterns quick reference
Async message handler (the safe pattern)
// Wrap async handlers to avoid the return-true trapfunction asyncHandler( fn: (msg: any, sender: chrome.runtime.MessageSender) => Promise<any>,) { return ( message: any, sender: chrome.runtime.MessageSender, sendResponse: (r: any) => void, ) => { fn(message, sender) .then(sendResponse) .catch((e) => sendResponse({ __error: true, message: e.message })); return true; // literal true, not Promise<true> };}chrome.runtime.onMessage.addListener( asyncHandler(async (msg, sender) => { if (msg.type === "FETCH") { const res = await fetch(msg.url); return { ok: res.ok, data: await res.text() }; } }),);
CSP bypass relay (content script → service worker → API)
// content-script.tsasync function apiCall(endpoint: string, options?: RequestInit) { return chrome.runtime.sendMessage({ type: "API_RELAY", endpoint, options });}// background.tsconst ALLOWED_ENDPOINTS = ["https://api.example.com"];chrome.runtime.onMessage.addListener( asyncHandler(async (msg) => { if (msg.type !== "API_RELAY") return; if (!ALLOWED_ENDPOINTS.some((e) => msg.endpoint.startsWith(e))) { throw new Error("Blocked endpoint"); } const res = await fetch(msg.endpoint, msg.options); return { ok: res.ok, status: res.status, data: await res.text() }; }),);
Persist state across SW restarts
// Use chrome.storage.session for ephemeral statechrome.storage.session.setAccessLevel({ accessLevel: "TRUSTED_AND_UNTRUSTED_CONTEXTS",});async function getState<T>(key: string, fallback: T): Promise<T> { const result = await chrome.storage.session.get(key); return result[key] ?? fallback;}async function setState<T>(key: string, value: T): Promise<void> { await chrome.storage.session.set({ [key]: value });}
Orphaned content script detection
function isExtensionContextValid(): boolean { try { return !!chrome.runtime?.id; } catch { return false; }}// Before any chrome.runtime callif (!isExtensionContextValid()) { showRefreshBanner(); return;}
What NOT to do
- Do NOT use
eval(),new Function(), or load remote scripts. MV3 forbids it. - Do NOT use
setTimeout/setIntervalfor anything > 5s in service workers. - Do NOT register event listeners inside callbacks or async functions.
- Do NOT use
<all_urls>host permission unless absolutely necessary. - Do NOT rely on DevTools keeping the service worker alive during testing.
- Do NOT forget
return truein async message listeners. - Do NOT use
localStorageorsessionStoragein service workers (they don't exist there). - Do NOT assume content scripts survive extension updates.
- Do NOT use
webRequestblocking (removed in MV3). UsedeclarativeNetRequest. - Do NOT use
chrome.extension.getBackgroundPage()(removed in MV3).
Все файлы
14 файловУстановить chrome-extension
Скачайте файлы навыков и распакуйте их в каталог .claude/skills/.
Скачать ZIPКлонируйте репозиторий и скопируйте файлы навыка в свой проект.
git clone https://github.com/samber/cc-skills/blob/main/skills/chrome-extension/SKILL.md # Copy SKILL.md to your .claude/skills/ directory
Копировать





Дом
