Skip to main content

Overview

React Grab’s plugin system allows you to extend functionality with custom context menu actions, toolbar items, lifecycle hooks, and theme overrides. Plugins provide a powerful way to integrate React Grab into your development workflow.

Plugin Interface

A plugin is an object that implements the Plugin interface:
string
required
Unique identifier for the plugin
DeepPartial<Theme>
Partial theme overrides to customize the visual appearance
SettableOptions
Override default options like activationMode, keyHoldDuration, maxContextLines, etc.
PluginAction[]
Array of context menu actions and/or toolbar menu items
PluginHooks
Lifecycle callbacks for events like activation, element selection, copying, etc.
(api: ReactGrabAPI, hooks: ActionContextHooks) => PluginConfig | void
Setup function called when plugin is registered. Receives the full ReactGrabAPI and can return additional configuration or a cleanup function.

Registering a Plugin

Simple Registration

Register a plugin directly on the global API:

React Component Registration

Register inside a useEffect to ensure React Grab is loaded:

Built-in Plugin Examples

Comment Plugin

The comment plugin adds context menu and toolbar actions for entering prompt mode:

Open Plugin

The open plugin allows opening source files in your editor:

Copy HTML Plugin

A more complex plugin that uses both hooks and actions:

Plugin Hooks

Plugins can listen to various lifecycle events:
() => void
Called when React Grab is activated
() => void
Called when React Grab is deactivated
(element: Element) => void
Called when hovering over an element
(element: Element) => boolean | void | Promise<boolean>
Called when an element is selected. Return true to prevent default selection behavior.
(elements: Element[]) => void | Promise<void>
Called before copying elements to clipboard
(content: string, elements: Element[]) => string | Promise<string>
Transform the content before it’s copied to clipboard
(elements: Element[], success: boolean) => void
Called after copy operation completes
(elements: Element[], content: string) => void
Called when copy succeeds
(error: Error) => void
Called when copy fails
(html: string, elements: Element[]) => string | Promise<string>
Transform HTML content before copying
(context: AgentContext, elements: Element[]) => AgentContext | Promise<AgentContext>
Transform the context passed to AI agents
(filePath: string, lineNumber?: number) => boolean | void
Handle file opening. Return true to prevent default behavior.
(url: string, filePath: string, lineNumber?: number) => string
Transform the URL used to open files in editor

PluginConfig

The setup function can return a PluginConfig object:
DeepPartial<Theme>
Theme overrides
SettableOptions
Option overrides
PluginAction[]
Actions to register
PluginHooks
Lifecycle hooks
() => void
Cleanup function called when the plugin is unregistered

Complete Example

Here’s a complete plugin that adds a custom analytics tracker:

Best Practices

  1. Unique Names: Always use unique plugin names to avoid conflicts
  2. Cleanup: Return a cleanup function from setup() to clean up resources
  3. Type Safety: Use TypeScript interfaces for better development experience
  4. Error Handling: Handle errors gracefully in async operations
  5. Performance: Avoid heavy operations in frequently called hooks like onElementHover
  6. Unregister: Always unregister plugins when components unmount in React

See Also