Loading...
Loading...
Install and configure react-grab to capture React component context (file path, component name, HTML markup) from any browser UI element for AI coding agents. Use when you want to point at a UI element in the browser and instantly copy its React component name, source file path, and HTML to clipboard for Claude Code, Cursor, Copilot, Gemini, or Codex. Triggers on: react-grab, grab, grab element context, copy component to ai, point and copy to claude, ui context clipboard, element to ai agent, click component copy, grab ui component, react component inspector, browser element context, component source file, copy element context, feed element to ai, element picker, grab react component, inspect element ai, component to clipboard, react devtools ai.
npx skill4agent add supercent-io/skills-template react-grabKeyword:·react-grab·grab·element contextcopy component to aiPoint at any UI element in your browser, press Cmd/Ctrl+C, and instantly copy its React component name, source file path, and HTML markup to clipboard — ready for your AI coding agent.
getElementContextfreezebash scripts/install.shnpx -y grab@latest initbash scripts/add-agent.sh mcpFor detailed API and framework-specific setup, see references/api.md.
# 1. Start your app
npm run dev
# 2. Hover over a button in the browser
# 3. Press Cmd+C (Mac) or Ctrl+C (Win/Linux)
# Clipboard now contains:
#
# in LoginForm at components/login-form.tsx:46:19
#
# <button class="btn-primary" type="submit">
# Log in
# </button>
# 4. Paste into Claude Code — it knows exactly where the component lives# Install react-grab MCP server
npx -y grab@latest add mcp
# Your AI agent can now call the get_element_context MCP tool
# to receive element context after you select it in the browserimport { registerPlugin } from "react-grab";
registerPlugin({
name: "open-in-figma",
actions: [{
id: "figma",
label: "Find in Figma",
shortcut: "F",
onAction: (ctx) => {
window.open(`figma://search?q=${ctx.componentName}`);
},
}],
});# One command — auto-detects your framework and installs everything
npx -y grab@latest init
# Add MCP server for programmatic AI agent access
npx -y grab@latest add mcp
# Add to a specific AI agent
npx -y grab@latest add claude-codeCmd+CCtrl+Cin LoginForm at components/login-form.tsx:46:19
<a class="ml-auto text-sm underline-offset-4 hover:underline">
Forgot your password?
</a>npx -y grab@latest initapp/layout.tsximport Script from 'next/script'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
{process.env.NODE_ENV === "development" && (
<Script
src="//unpkg.com/react-grab/dist/index.global.js"
crossOrigin="anonymous"
strategy="beforeInteractive"
/>
)}
</body>
</html>
)
}pages/_document.tsximport Script from 'next/script'
// Inside _document component:
{process.env.NODE_ENV === "development" && (
<Script
src="//unpkg.com/react-grab/dist/index.global.js"
crossOrigin="anonymous"
strategy="beforeInteractive"
/>
)}index.html<script type="module">
if (import.meta.env.DEV) {
await import('//unpkg.com/react-grab/dist/index.global.js');
}
</script>if (process.env.NODE_ENV === 'development') {
import('react-grab');
}npm install react-grab
# or: pnpm add react-grab | yarn add react-grab | bun add react-grab# Auto-detect framework and install
bash scripts/install.sh
# Install for a specific framework
bash scripts/install.sh --framework next-app
# Add to a specific AI agent
bash scripts/add-agent.sh claude-code
bash scripts/add-agent.sh cursor
bash scripts/add-agent.sh mcpin <ComponentName> at <file-path>:<line>:<col>
<element-html>import { getGlobalApi } from "react-grab";
const api = getGlobalApi();
// Activate the overlay
api.activate(); // show overlay
api.deactivate(); // hide overlay
api.toggle(); // toggle
// Copy an element's context to clipboard
await api.copyElement(document.querySelector('.my-button'));
// Get source info without copying
const source = await api.getSource(element);
console.log(source.filePath); // "src/components/Button.tsx"
console.log(source.lineNumber); // 42
console.log(source.componentName); // "Button"
// Get the full stack context string
const stack = await api.getStackContext(element);
// "in Button (at Button.tsx:42:5)\n in Card (at Card.tsx:10:3)"
// Check current state
const state = api.getState();
// { isActive, isDragging, isCopying, targetElement, ... }import { getElementContext, freeze, unfreeze, openFile } from "react-grab/primitives";
// or: import { getElementContext } from "react-grab/core";
const button = document.querySelector('.submit-btn');
// Freeze page state (pause React updates, CSS animations, preserve :hover/:focus)
freeze();
// Get all context for an element
const context = await getElementContext(button);
console.log(context.componentName); // "SubmitButton"
console.log(context.selector); // "button.submit-btn"
console.log(context.stackString); // "in SubmitButton (at Button.tsx:12:5)"
console.log(context.htmlPreview); // "<button class=\"submit-btn\">Submit</button>"
console.log(context.styles); // Relevant computed CSS
unfreeze(); // Restore normal page behavior
// Open the source file in editor
await openFile("/src/components/Button.tsx", 12);@react-grab/mcp# Add MCP server
npx -y grab@latest add mcpget_element_contextget_element_contextnpx -y grab@latest add claude-code # Claude Code
npx -y grab@latest add cursor # Cursor
npx -y grab@latest add copilot # GitHub Copilot
npx -y grab@latest add codex # OpenAI Codex
npx -y grab@latest add gemini # Google Gemini CLI
npx -y grab@latest add opencode # OpenCode
npx -y grab@latest add amp # Amp
npx -y grab@latest add droid # Droidnpx -y grab@latest remove cursorimport { registerPlugin } from "react-grab";
registerPlugin({
name: "send-to-jira",
hooks: {
// Add annotation to clipboard content
transformCopyContent: async (content, elements) => {
return content + "\n// Sent from react-grab";
},
// Custom file-open behavior
onOpenFile: (filePath, lineNumber) => {
// Return true if handled; false to use default behavior
return false;
},
},
actions: [
{
id: "jira-action",
label: "Create Jira Ticket",
shortcut: "J",
onAction: async (context) => {
await createJiraTicket({
filePath: context.filePath,
componentName: context.componentName,
html: context.element.outerHTML,
});
context.hideContextMenu();
},
},
{
id: "toolbar-inspect",
label: "Inspect",
target: "toolbar", // Places in toolbar instead of context menu
onAction: () => {
console.log("Inspect triggered");
},
},
],
theme: {
hue: 200, // Change overlay color (0-360 HSL)
crosshair: { enabled: false }, // Disable crosshair overlay
},
});hooks: {
onActivate?: () => void
onDeactivate?: () => void
onElementHover?: (element: Element) => void
onElementSelect?: (element: Element) => boolean | void // return true to cancel default
onBeforeCopy?: (elements: Element[]) => void
transformCopyContent?: (content: string, elements: Element[]) => string | Promise<string>
onAfterCopy?: (elements: Element[], success: boolean) => void
onOpenFile?: (filePath: string, lineNumber?: number) => boolean | void
transformHtmlContent?: (html: string, elements: Element[]) => string | Promise<string>
transformAgentContext?: (ctx: AgentContext, elements: Element[]) => AgentContext
transformSnippet?: (snippet: string, element: Element) => string | Promise<string>
}grab [command] [options]
Commands:
init Auto-detect project and install react-grab
add Connect react-grab to an AI coding agent (alias: install)
remove Disconnect from an AI coding agent
configure Configure options (activation key, context lines, etc.)
Options:
-y, --yes Skip confirmation prompts
-c, --cwd Working directory (default: process.cwd())
-v, --version Display version
-h, --help Display helpinit()import { init } from "react-grab";
init({
enabled: true, // Enable/disable entirely
activationMode: "toggle", // "toggle" | "hold"
activationKey: "c", // Key to press (with Cmd/Ctrl)
maxContextLines: 10, // Limit React component stack depth
freezeReactUpdates: true, // Pause React state while active
getContent: async (elements) => { // Custom clipboard content formatter
const contexts = await generateSnippet(elements);
return contexts.join("\n---\n");
},
});window.__REACT_GRAB_DISABLED__ = true;NODE_ENV === "development"import.meta.env.DEVinitnpx -y grab@latest initgrab add mcpfreeze()| Issue | Solution |
|---|---|
| Overlay not appearing | Check |
Component name shows as | Ensure |
| File path missing | Requires React source maps enabled (dev mode only; not minified builds) |
| MCP tool returns empty | You need to select an element in the browser first before calling |
| Check Node.js >=18 and package manager (npm/pnpm/yarn/bun) is installed |
install.shadd-agent.sh