Claude Code से Chrome Extension बनाना: MV3, Messaging और Minimum Permissions
Claude Code से Chrome MV3 extension बनाएं: manifest, service worker, content script, permissions, storage और tests.
पहले extension की boundary तय करें
Chrome extension छोटा project लग सकता है, लेकिन इसमें manifest.json, Manifest V3, service worker, content script, messaging, permissions, storage, security review, packaging और Chrome Web Store के लिए साफ explanation सब शामिल होते हैं। अगर आप Claude Code से सिर्फ “Chrome extension बना दो” कहेंगे, तो वह popup, React, Vite, <all_urls>, tabs और external scripts के साथ बहुत बड़ा scaffold बना सकता है।
इस guide में हम छोटा और review-friendly example बनाएंगे। Extension https://example.com/* पर selected text को context menu से highlight करेगा। हम plain JavaScript, chrome.storage.local, service worker, content script और runtime messages का इस्तेमाल करेंगे। कोई broad permission, remote code, CDN script या unnecessary host access नहीं होगा। इससे code copy-paste करके चलाना आसान होता है और permissions explain करना भी आसान रहता है।
कुछ terms साफ कर लेते हैं। Manifest V3 Chrome extension का current manifest format है। service worker background में event आने पर wake up होता है, हमेशा running process नहीं रहता। content script page में inject होकर DOM read या modify कर सकता है। message passing extension के अलग contexts के बीच JSON messages भेजने का तरीका है। अगर agentic development में harness शब्द दिखे, तो इसे “agent के काम करने की सुरक्षित जगह या scaffold” समझें।
Official docs को साथ में रखें: Chrome Extensions Manifest, About extension service workers, Chrome Content scripts, MDN Content scripts, Chrome Declare permissions और MDN permissions। Claude Code prompts बेहतर करने के लिए Claude Code productivity tips भी देखें।
तीन practical use cases
पहला use case internal documentation review है। Extension को https://docs.example.com/* तक सीमित रखें और release notes में product terms highlight करें। URL scope narrow है, इसलिए security reviewer को समझाना आसान है कि extension सिर्फ docs domain पर काम करता है।
दूसरा use case support team workflow है। Agent admin page में order ID select कर सकता है और context menu से उसे highlight या copy कर सकता है। इस case में personal data दिख सकता है, इसलिए Claude Code से table बनवाएं: extension क्या read करता है, क्या store करता है, क्या send करता है और क्या ignore करता है।
तीसरा use case content और SEO QA है। Content script draft article page पर description length, h2 count, internal links और official external links check कर सकता है। CLI checks के लिए Claude Code CLI tool development और security review के लिए Claude Code security best practices उपयोगी हैं।
Claude Code prompt
Prompt में feature, restrictions और verification तीनों दें। MV3 में service worker persistent नहीं होता और permissions minimum रखनी होती हैं।
Manifest V3 Chrome extension sample बनाइए।
Requirements:
- Target URL सिर्फ https://example.com/* हो
- Context menu से selected text highlight हो
- Plain JavaScript files use करें: manifest.json, service-worker.js, content-script.js
- chrome.storage.local में enabled और color save करें
- Content script से runtime messages के जरिए communicate करें
- <all_urls>, tabs, eval, external CDN scripts और remote code use न करें
- Playwright smoke script जोड़ें जो extension load होना verify करे
- Chrome docs के आधार पर permission review table बनाएं
पहली version में scope छोटा रखें। अगर Claude Code popup, options page, icons, bundler और broad permissions जोड़ दे, तो उससे पहले sample reduce करवाएं।
File structure और Manifest
यह folder chrome://extensions में Load unpacked से load हो सकता है।
mv3-highlighter/
manifest.json
service-worker.js
content-script.js
package.json
playwright-extension-smoke.mjs
{
"manifest_version": 3,
"name": "Claude Code MV3 Highlighter",
"version": "0.1.0",
"description": "Highlights selected text on example.com from a context menu.",
"action": {
"default_title": "MV3 Highlighter"
},
"permissions": ["contextMenus", "storage"],
"background": {
"service_worker": "service-worker.js",
"type": "module"
},
"content_scripts": [
{
"matches": ["https://example.com/*"],
"js": ["content-script.js"],
"run_at": "document_idle"
}
]
}
| Area | Setting | Reason | Avoided |
|---|---|---|---|
| API permissions | contextMenus, storage | Menu और settings | tabs, scripting, downloads |
| Page access | https://example.com/* | सिर्फ demo domain | <all_urls> |
| Host permissions | none | Static content script काफी है | broad host access |
| Remote code | none | MV3 review आसान | CDN, eval |
Service worker code
Service worker events receive करता है और content script को message भेजता है। यह हमेशा alive नहीं रहता, इसलिए important settings memory में नहीं, storage में रखें।
const MENU_ID = "highlight-selection";
const DEFAULT_SETTINGS = {
enabled: true,
color: "#fff176"
};
async function readSettings() {
return chrome.storage.local.get(DEFAULT_SETTINGS);
}
chrome.runtime.onInstalled.addListener(async () => {
const settings = await readSettings();
await chrome.storage.local.set(settings);
chrome.contextMenus.create({
id: MENU_ID,
title: "Highlight selected text",
contexts: ["selection"],
documentUrlPatterns: ["https://example.com/*"]
});
});
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
if (info.menuItemId !== MENU_ID || !tab?.id || !info.selectionText) {
return;
}
const settings = await readSettings();
await chrome.tabs.sendMessage(tab.id, {
type: "HIGHLIGHT_SELECTION",
text: info.selectionText.slice(0, 120),
enabled: settings.enabled,
color: settings.color
});
});
chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
if (message?.type === "GET_SETTINGS") {
readSettings().then(sendResponse);
return true;
}
if (message?.type === "SAVE_SETTINGS") {
const nextSettings = {
enabled: Boolean(message.enabled),
color: String(message.color || DEFAULT_SETTINGS.color)
};
chrome.storage.local.set(nextSettings).then(() => {
sendResponse({ ok: true, settings: nextSettings });
});
return true;
}
return false;
});
Common pitfall: async sendResponse के साथ return true भूल जाना। Promise complete होने से पहले message channel बंद हो सकता है। इसे Chrome Message passing के साथ review करें।
Content script code
Content script page DOM modify करता है, लेकिन secrets या API keys रखने की जगह नहीं है। यह service worker से message receive करता है और selected text highlight करता है।
const HIGHLIGHT_CLASS = "cc-mv3-highlight";
document.documentElement.dataset.ccMv3Highlighter = "ready";
function shouldSkipNode(node) {
const parent = node.parentElement;
if (!parent) return true;
return Boolean(
parent.closest(
`script, style, textarea, input, [contenteditable="true"], .${HIGHLIGHT_CLASS}`
)
);
}
function clearHighlights() {
for (const mark of document.querySelectorAll(`.${HIGHLIGHT_CLASS}`)) {
const text = document.createTextNode(mark.textContent || "");
mark.replaceWith(text);
text.parentElement?.normalize();
}
}
function createMark(text, color) {
const mark = document.createElement("mark");
mark.className = HIGHLIGHT_CLASS;
mark.textContent = text;
mark.style.backgroundColor = color;
mark.style.color = "#111";
mark.style.padding = "0 2px";
return mark;
}
function highlightText(term, color) {
const query = term.trim();
if (!query) return 0;
clearHighlights();
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
acceptNode(node) {
if (shouldSkipNode(node)) return NodeFilter.FILTER_REJECT;
return node.nodeValue.toLowerCase().includes(query.toLowerCase())
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_SKIP;
}
});
const matches = [];
while (walker.nextNode()) {
const node = walker.currentNode;
const index = node.nodeValue.toLowerCase().indexOf(query.toLowerCase());
if (index >= 0) matches.push({ node, index });
}
for (const { node, index } of matches.reverse()) {
const selected = node.splitText(index);
selected.splitText(query.length);
selected.replaceWith(createMark(selected.nodeValue, color));
}
return matches.length;
}
chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
if (message?.type !== "HIGHLIGHT_SELECTION") {
return false;
}
if (!message.enabled) {
clearHighlights();
sendResponse({ ok: true, count: 0 });
return false;
}
const count = highlightText(String(message.text || ""), message.color || "#fff176");
sendResponse({ ok: true, count });
return false;
});
यह simple highlighter है। यह हर text node में first match highlight करता है और form, script, style, contenteditable areas skip करता है। Production में repeated matches, Shadow DOM, dynamic content और existing mark elements test करें।
Playwright और manual test
Playwright में launchPersistentContext से unpacked extension load किया जा सकता है।
{
"type": "module",
"scripts": {
"smoke": "node playwright-extension-smoke.mjs"
},
"devDependencies": {
"playwright": "^1.52.0"
}
}
import { chromium } from "playwright";
import path from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const extensionPath = path.resolve(__dirname);
const userDataDir = path.resolve(__dirname, ".pw-extension-profile");
const context = await chromium.launchPersistentContext(userDataDir, {
headless: false,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`
]
});
const page = await context.newPage();
await page.goto("https://example.com/");
await page.waitForFunction(() => {
return document.documentElement.dataset.ccMv3Highlighter === "ready";
});
console.log("Extension content script is loaded on https://example.com/");
await page.waitForTimeout(3000);
await context.close();
npm install
npm run smoke
Manual checklist: chrome://extensions खोलें, Developer mode enable करें, Load unpacked से folder load करें, https://example.com/ खोलें, heading का text select करें और “Highlight selected text” चलाएं। Service worker console में errors न हों।
Pitfalls, packaging और result note
Main pitfalls हैं: unnecessary tabs permission, content script में secrets रखना, service worker memory पर भरोसा करना, innerHTML से DOM तोड़ना, और debugging के बाद <all_urls> हटाना भूल जाना। Publishing से पहले Prepare your Extension के अनुसार icons, screenshots, privacy explanation और permission justification तैयार करें।
zip -r mv3-highlighter.zip manifest.json service-worker.js content-script.js
Compress-Archive -Path manifest.json,service-worker.js,content-script.js -DestinationPath mv3-highlighter.zip -Force
Monetization सिर्फ code generation में नहीं है। असली value permission review, security boundary, test checklist और store explanation को repeatable process बनाने में है। ClaudeCodeLab की Claude Code training और consulting MV3 design, review prompts और validation checklist को real repository के साथ整理 करने में मदद कर सकती है। Self-paced templates के लिए product library देखें।
Masa ने यह pattern try किया तो सबसे बड़ा issue JavaScript नहीं, permissions explanation था। <all_urls> से demo जल्दी बनता है, पर user को यह बताना मुश्किल है कि सभी sites की access क्यों चाहिए। https://example.com/* और सिर्फ contextMenus plus storage रखने पर Chrome warning कम हुई और Claude Code review ज्यादा useful हुआ। MV3 extension में “चल गया” से ज्यादा जरूरी है “समझाने योग्य permissions के साथ चला”।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code Obsidian to CLAUDE.md workflow: context बार-बार न समझाएं
Obsidian notes को CLAUDE.md operating notes में बदलकर Claude Code sessions को resume करना आसान बनाएं.
Claude Code Revenue CTA Routing: article से PDF, Gumroad और consultation तक
Reader intent के आधार पर free PDF, Gumroad products और consultation तक CTA route करने वाला workflow.
Claude Code टीम हैंडऑफ नियम: review proof, permissions, rollback और revenue path
Claude Code टीम काम के लिए evidence, permission rules, rollback, free PDF, Gumroad और consultation path वाला handoff.