{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "api-core-plate-plugin-docs",
  "title": "Plate Plugin",
  "description": "API reference for Plate plugins.",
  "files": [
    {
      "path": "../../content/docs/api/core/plate-plugin.mdx",
      "content": "---\ntitle: Plate Plugin\ndescription: API reference for Plate plugins.\n---\n\nPlate plugins are objects passed to `Plate` [plugins](/docs/api/core/plate-components#plugins) prop.\n\n## Plugin Properties\n\n<API name=\"Properties\">\n<APIAttributes>\n<APIItem name=\"key\" type=\"C['key']\" required>\nUnique identifier used by Plate to store the plugins by key in `editor.plugins`.\n</APIItem>\n\n<APIItem name=\"api\" type=\"Record<string, Function>\">\nAn object of API functions provided by the plugin. These functions are accessible via `editor.api[key]`.\n</APIItem>\n\n<APIItem name=\"transforms\" type=\"Record<string, Function>\">\nTransform functions provided by the plugin that modify the editor state. These are accessible via `editor.tf[key]`.\n</APIItem>\n\n<APIItem name=\"options\" type=\"Record<string, any>\">\nExtended properties used by the plugin as options.\n</APIItem>\n\n<APIItem name=\"handlers\" type=\"{ onChange?: (editor: PlateEditor) => void } & Record<string, Function>\">\nEvent handlers for various editor events.\n\n<APISubList>\n<APISubListItem parent=\"handlers\" name=\"onChange\" type=\"(editor: PlateEditor) => void\" optional>\nCalled whenever the editor content changes.\n</APISubListItem>\n<APISubListItem parent=\"handlers\" name=\"onNodeChange\" type=\"OnNodeChange\" optional>\nCalled whenever a node operation occurs (insert, remove, set, merge, split, move).\n\n```ts\ntype OnNodeChange = (ctx: PlatePluginContext & {\n  node: Descendant;\n  operation: NodeOperation;\n  prevNode: Descendant;\n}) => HandlerReturnType;\n```\n\n**Parameters:**\n- `node`: The node after the operation\n- `operation`: The node operation that occurred\n- `prevNode`: The node before the operation\n\n**Note:** For `insert_node` and `remove_node` operations, both `node` and `prevNode` contain the same value to avoid null cases.\n</APISubListItem>\n<APISubListItem parent=\"handlers\" name=\"onTextChange\" type=\"OnTextChange\" optional>\nCalled whenever a text operation occurs (insert or remove text).\n\n```ts\ntype OnTextChange = (ctx: PlatePluginContext & {\n  node: Descendant;\n  operation: TextOperation;\n  prevText: string;\n  text: string;\n}) => HandlerReturnType;\n```\n\n**Parameters:**\n- `node`: The parent node containing the text that changed\n- `operation`: The text operation that occurred (`insert_text` or `remove_text`)\n- `prevText`: The text content before the operation\n- `text`: The text content after the operation\n</APISubListItem>\n</APISubList>\n</APIItem>\n\n<APIItem name=\"inject\" type=\"object\">\nDefines how the plugin injects functionality into other plugins or the editor.\n\n<APISubList>\n<APISubListItem parent=\"inject\" name=\"nodeProps\" type=\"Record<string, any>\" optional>\nProperties used by Plate to inject props into any node component.\n</APISubListItem>\n\n\n<APISubListItem parent=\"inject\" name=\"excludePlugins\" type=\"string[]\" optional>\nAn array of plugin keys to exclude from node prop injection.\n</APISubListItem>\n\n<APISubListItem parent=\"inject\" name=\"excludeBelowPlugins\" type=\"string[]\" optional>\nAn array of plugin keys. Node prop injection will be excluded for any nodes that are descendants of elements with these plugin types.\n</APISubListItem>\n<APISubListItem parent=\"inject\" name=\"isBlock\" type=\"boolean\" optional>\nIf true, only matches block elements. Used to restrict prop injection to block-level nodes.\n</APISubListItem>\n\n<APISubListItem parent=\"inject\" name=\"isElement\" type=\"boolean\" optional>\nIf true, only matches element nodes. Used to restrict prop injection to element nodes.\n</APISubListItem>\n<APISubListItem parent=\"inject\" name=\"isLeaf\" type=\"boolean\" optional>\nIf true, only matches leaf nodes. Used to restrict prop injection to leaf nodes.\n</APISubListItem>\n<APISubListItem parent=\"inject\" name=\"maxLevel\" type=\"number\" optional>\nMaximum nesting level for node prop injection. Nodes deeper than this level will not receive injected props.\n</APISubListItem>\n<APISubListItem parent=\"inject\" name=\"plugins\" type=\"Record<string, Partial<PlatePlugin>>\" optional>\nProperty that can be used by a plugin to allow other plugins to inject code.\n</APISubListItem>\n<APISubListItem parent=\"inject\" name=\"targetPluginToInject\" type=\"function\" optional>\nA function that returns a plugin config to be injected into other plugins `inject.plugins` specified by targetPlugins.\n</APISubListItem>\n<APISubListItem parent=\"inject\" name=\"targetPlugins\" type=\"string[]\" optional>\nPlugin keys used by `InjectNodeProps` and the `targetPluginToInject` function.\n\n- **Default:** `[ParagraphPlugin.key]`\n</APISubListItem>\n</APISubList>\n</APIItem>\n\n<APIItem name=\"node\" type=\"object\">\nDefines the node-specific configuration for the plugin.\n\n<APISubList>\n<APISubListItem parent=\"node\" name=\"isDecoration\" type=\"boolean\" optional>\nIndicates if this plugin's nodes can be rendered as decorated leaf. Set to false to render node component only once per text node.\n\n- **Default:** `true`\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isElement\" type=\"boolean\" optional>\nIndicates if this plugin's nodes should be rendered as elements.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isInline\" type=\"boolean\" optional>\nIndicates if this plugin's elements should be treated as inline.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isLeaf\" type=\"boolean\" optional>\nIndicates if this plugin's nodes should be rendered as leaves.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isContainer\" type=\"boolean\" optional>\nWhen `true`, indicates that the plugin's elements are primarily containers for other content. This property is typically used by fragment queries to unwrap the container nodes.\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"selection.affinity\" type=\"'default' | 'directional' | 'outward' | 'hard'\" optional>\nDefines the selection behavior at the boundaries of nodes. See [Plugin Rules](/docs/plugin-rules#rulesselection).\n\n- `'default'`: Uses Slate's default behavior\n- `'directional'`: Selection affinity is determined by the direction of cursor movement. Maintains inward or outward affinity based on approach\n- `'outward'`: Forces outward affinity. Typing at the edge of a mark will not apply the mark to new text\n- `'hard'`: Creates a 'hard' edge that requires two key presses to move across. Uses offset-based navigation\n\n- **Default:** `undefined` (Slate's default behavior)\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isMarkableVoid\" type=\"boolean\" optional>\nIndicates if this plugin's void elements should be markable.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isSelectable\" type=\"boolean\" optional>\nIndicates if this plugin's nodes should be selectable.\n\n- **Default:** `true`\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isStrictSiblings\" type=\"boolean\" optional>\nIndicates whether this element enforces strict sibling type constraints. Set to `true` when the element only allows specific siblings (e.g., `td` can only have `td` siblings, `column` can only have `column` siblings) and prevents standard text blocks like paragraphs from being inserted as siblings.\n\nUsed by exit break functionality to determine appropriate exit points in nested structures. See [Exit Break](/docs/exit-break).\n\n- **Default:** `false`\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"break.empty\" type=\"'default' | 'deleteExit' | 'exit' | 'lift' | 'reset'\" optional>\nAction when Enter is pressed in an empty block. See [Plugin Rules](/docs/plugin-rules).\n\n- `'default'`: Default behavior\n- `'reset'`: Reset block to default paragraph type\n- `'exit'`: Exit the current block\n- `'lift'`: Lift the current block out of the nearest matching ancestor\n- `'deleteExit'`: Delete backward then exit\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"break.emptyLineEnd\" type=\"'default' | 'deleteExit' | 'exit'\" optional>\nAction when Enter is pressed at the end of an empty line. This is typically used with `rules.break.default: 'lineBreak'`. See [Plugin Rules](/docs/plugin-rules).\n\n- `'default'`: Default behavior\n- `'exit'`: Exit the current block\n- `'deleteExit'`: Delete backward then exit\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"break.default\" type=\"'default' | 'deleteExit' | 'exit' | 'lineBreak'\" optional>\nDefault action when Enter is pressed. Defaults to splitting the block. See [Plugin Rules](/docs/plugin-rules).\n\n- `'default'`: Default behavior\n- `'exit'`: Exit the current block\n- `'lineBreak'`: Insert newline character\n- `'deleteExit'`: Delete backward then exit\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"break.splitReset\" type=\"boolean\" optional>\nIf true, the new block after splitting will be reset to the default type. See [Plugin Rules](/docs/plugin-rules).\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"delete.start\" type=\"'default' | 'lift' | 'reset'\" optional>\nAction when Backspace is pressed at the start of the block. This applies whether the block is empty or not. See [Plugin Rules](/docs/plugin-rules).\n\n- `'default'`: Default behavior\n- `'lift'`: Lift the current block out of the nearest matching ancestor\n- `'reset'`: Reset block to default paragraph type\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"delete.empty\" type=\"'default' | 'reset'\" optional>\nAction when Backspace is pressed and the block is empty. See [Plugin Rules](/docs/plugin-rules).\n\n- `'default'`: Default behavior\n- `'reset'`: Reset block to default paragraph type\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"match\" type=\"MatchRules\" optional>\nFunction to determine if this plugin's rules should apply to a node. Used to override behavior based on node properties beyond just type matching.\n\n**Default:** `type === node.type`\n\n**Example:** `matchRules: ({ node }) => Boolean(node.listStyleType)`\n\nExample: List plugin sets `match: ({ node }) => !!node.listStyleType` to override paragraph behavior when the paragraph is a list item.\n\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"merge.removeEmpty\" type=\"boolean\" optional>\nWhether to remove the node when it's empty during merge operations. See [Plugin Rules](/docs/plugin-rules).\n\n- **Default:** `false`\n</APISubListItem>\n<APISubListItem parent=\"rules\" name=\"normalize.removeEmpty\" type=\"boolean\" optional>\nWhether to remove nodes with empty text during normalization. See [Plugin Rules](/docs/plugin-rules).\n\n- **Default:** `false`\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"isVoid\" type=\"boolean\" optional>\nIndicates if this plugin's elements should be treated as void.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"type\" type=\"string\" optional>\nSpecifies the type identifier for this plugin's nodes. \n\n- **Default:** `plugin.key`\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"component\" type=\"NodeComponent | null\" optional>\nReact component used to render this plugin's nodes.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"leafProps\" type=\"LeafNodeProps<WithAnyKey<C>>\" optional>\nOverride `data-slate-leaf` element attributes.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"props\" type=\"NodeProps<WithAnyKey<C>>\" optional>\nOverride node attributes.\n</APISubListItem>\n<APISubListItem parent=\"node\" name=\"textProps\" type=\"TextNodeProps<WithAnyKey<C>>\" optional>\nOverride `data-slate-node=\"text\"` element attributes.\n</APISubListItem>\n</APISubList>\n</APIItem>\n\n<APIItem name=\"override\" type=\"object\">\nAllows overriding components and plugins by key.\n\n<APISubList>\n<APISubListItem parent=\"override\" name=\"components\" type=\"Record<string, NodeComponent>\" optional>\nReplace plugin `NodeComponent` by key.\n</APISubListItem>\n<APISubListItem parent=\"override\" name=\"plugins\" type=\"Record<string, Partial<EditorPlatePlugin<AnyPluginConfig>>>\" optional>\nExtend `PlatePlugin` by key.\n</APISubListItem>\n<APISubListItem parent=\"override\" name=\"enabled\" type=\"Partial<Record<string, boolean>>\" optional>\nEnable or disable plugins.\n</APISubListItem>\n</APISubList>\n</APIItem>\n\n<APIItem name=\"parser\" type=\"Nullable<Parser<WithAnyKey<C>>>\">\nDefines how the plugin parses content.\n</APIItem>\n\n<APIItem name=\"parsers\" type=\"object\">\nDefines serializers and deserializers for various formats.\n\n<APISubList>\n<APISubListItem parent=\"parsers\" name=\"html\" type=\"Nullable<{ deserializer?: HtmlDeserializer<WithAnyKey<C>>; serializer?: HtmlSerializer<WithAnyKey<C>> }>\" optional>\nHTML parser configuration.\n</APISubListItem>\n<APISubListItem parent=\"parsers\" name=\"htmlReact\" type=\"Nullable<{ serializer?: HtmlReactSerializer<WithAnyKey<C>> }>\" optional>\nHTML React serializer configuration.\n</APISubListItem>\n</APISubList>\n</APIItem>\n\n<APIItem name=\"render\" type=\"object\">\nDefines how the plugin renders components.\n\n<APISubList>\n<APISubListItem parent=\"render\" name=\"aboveEditable\" type=\"Component\" optional>\nComponent rendered above the Editable component but inside the Slate wrapper.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"aboveNodes\" type=\"RenderNodeWrapper<WithAnyKey<C>>\" optional>\nCreate a function that generates a parent React node for all other plugins' node components.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"aboveSlate\" type=\"Component\" optional>\nComponent rendered above the Slate wrapper.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"afterEditable\" type=\"EditableSiblingComponent\" optional>\nRenders a component after the Editable component.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"beforeEditable\" type=\"EditableSiblingComponent\" optional>\nRenders a component before the Editable component.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"belowNodes\" type=\"RenderNodeWrapper<WithAnyKey<C>>\" optional>\nCreate a function that generates a React node below all other plugins' node React node, but above their children.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"belowRootNodes\" type=\"(props: PlateElementProps<TElement, C>) => React.ReactNode\" optional>\nRenders a component after the direct children of the root element. This differs from `belowNodes` in that it's the direct child of `PlateElement` rather than wrapping the children that could be nested. This is useful when you need components relative to the root element.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"leaf\" type=\"NodeComponent\" optional>\nRenders a component below leaf nodes when `isLeaf: true` and `isDecoration: false`. Use `render.node` instead when `isDecoration: true`.\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"node\" type=\"NodeComponent\" optional>\nRenders a component for:\n- Elements nodes if `isElement: true`\n- Below text nodes if `isLeaf: true` and `isDecoration: false`\n- Below leaf if `isLeaf: true` and `isDecoration: true`\n</APISubListItem>\n<APISubListItem parent=\"render\" name=\"as\" type=\"keyof HTMLElementTagNameMap\" optional>\nSpecifies the HTML tag name to use when rendering the node component. Only used when no custom `component` is provided for the plugin.\n\n- **Default:** `'div'` for elements, `'span'` for leaves\n\n</APISubListItem>\n</APISubList>\n</APIItem>\n\n<APIItem name=\"shortcuts\" type=\"Shortcuts\">\nDefines keyboard shortcuts for the plugin.\n</APIItem>\n\n<APIItem name=\"useOptionsStore\" type=\"StoreApi<C['key'], C['options']>\">\nZustand store for managing plugin options.\n</APIItem>\n\n<APIItem name=\"dependencies\" type=\"string[]\">\nAn array of plugin keys that this plugin depends on.\n</APIItem>\n\n<APIItem name=\"enabled\" type=\"boolean\" optional>\nEnables or disables the plugin. Used by Plate to determine if the plugin should be used.\n</APIItem>\n\n<APIItem name=\"plugins\" type=\"any[]\">\nRecursive plugin support to allow having multiple plugins in a single plugin.\n</APIItem>\n\n<APIItem name=\"priority\" type=\"number\">\nDefines the order in which plugins are registered and executed.\n\n- **Default:** `100`\n</APIItem>\n\n<APIItem name=\"decorate\" type=\"Decorate<WithAnyKey<C>>\" optional>\nProperty used by Plate to decorate editor ranges.\n</APIItem>\n\n<APIItem name=\"extendEditor\" type=\"ExtendEditor<WithAnyKey<C>>\" optional>\nFunction to extend the editor instance. Used primarily for integrating legacy Slate plugins that need direct editor mutation. Only one `extendEditor` is allowed per plugin.\n\n```ts\nextendEditor: ({ editor }) => {\n  // Example: Integrating a legacy Slate plugin\n  return withYjs(editor);\n}\n```\n</APIItem>\n\n<APIItem name=\"useHooks\" type=\"() => void\" optional>\nHook called when the editor is initialized.\n</APIItem>\n\n<APIItem name=\"editOnly\" type=\"boolean | EditOnlyConfig\" optional>\nConfigures which plugin functionalities should only be active when the editor is not read-only.\n\nCan be either a boolean or an object configuration:\n\n```ts\ntype EditOnlyConfig = {\n  render?: boolean;      // default: true\n  handlers?: boolean;    // default: true\n  inject?: boolean;      // default: true\n  transformInitialValue?: boolean;  // default: false\n}\n```\n\nWhen set to `true` (boolean):\n- `render`, `handlers`, and `inject.nodeProps` are only active when editor is not read-only\n- `transformInitialValue` remains active regardless of read-only state\n\nWhen set to an object:\n- Each property can be individually configured\n- Properties default to being edit-only (`true`) except `transformInitialValue` which defaults to always active (`false`)\n- Set a property to `false` to make it always active regardless of read-only state\n- For `transformInitialValue`, set to `true` to make it edit-only\n\nExamples:\n```ts\n// All features (except transformInitialValue) are edit-only\neditOnly: true\n\n// transformInitialValue is edit-only, others remain edit-only by default\neditOnly: { transformInitialValue: true }\n\n// render is always active, others follow default behavior\neditOnly: { render: false }\n```\n</APIItem>\n</APIAttributes>\n</API>\n\n## Plugin Methods\n\n<API name=\"Methods\">\n<APIMethods>\n<APIItem name=\"configure\" type=\"(config: PlatePluginConfig | ((ctx: PlatePluginContext) => PlatePluginConfig)) => PlatePlugin\">\nCreates a new plugin instance with updated options.\n\n```ts\n(config: PlatePluginConfig<C['key'], InferOptions<C>, InferApi<C>, InferTransforms<C>> | ((ctx: PlatePluginContext<C>) => PlatePluginConfig<C['key'], InferOptions<C>, InferApi<C>, InferTransforms<C>>)) => PlatePlugin<C>\n```\n</APIItem>\n\n<APIItem name=\"extend\" type=\"(config: Partial<PlatePlugin> | ((ctx: PlatePluginContext) => Partial<PlatePlugin>)) => PlatePlugin\">\nCreates a new plugin instance with additional configuration.\n\n```ts\n(extendConfig: Partial<PlatePlugin> | ((ctx: PlatePluginContext<AnyPluginConfig>) => Partial<PlatePlugin>)) => PlatePlugin\n```\n</APIItem>\n\n<APIItem name=\"extendPlugin\" type=\"(key: string, config: Partial<PlatePlugin> | ((ctx: PlatePluginContext) => Partial<PlatePlugin>)) => PlatePlugin\">\nExtends an existing nested plugin or adds a new one if not found. Supports deep nesting.\n\n```ts\n(key: string, extendConfig: Partial<PlatePlugin> | ((ctx: PlatePluginContext<AnyPluginConfig>) => Partial<PlatePlugin>)) => PlatePlugin\n```\n</APIItem>\n\n<APIItem name=\"withComponent\" type=\"function\">\nSets or replaces the component associated with a plugin.\n\n```ts\n(component: NodeComponent) => PlatePlugin<C>\n```\n</APIItem>\n\n<APIItem name=\"overrideEditor\" type=\"function\">\nCreates a new plugin instance with overridden editor methods. Provides access to original methods via `tf` and `api` parameters. Can be called multiple times to layer different overrides.\n\n```ts\noverrideEditor(({ editor, tf: { deleteForward }, api: { isInline } }) => ({\n  transforms: {\n    // Override transforms\n    deleteForward(options) {\n      deleteForward(options);\n    },\n  },\n  api: {\n    // Override API methods\n    isInline(element) {\n      return isInline(element);\n    },\n  },\n})) => PlatePlugin<C>\n```\n\n- Preferred method for modifying editor behavior\n- Type-safe access to original methods\n- Clean separation between transforms and API\n- Can be chained multiple times\n</APIItem>\n\n<APIItem name=\"extendApi\" type=\"(api: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\">\nExtends the plugin's API.\n\n```ts\n(api: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\n```\n</APIItem>\n\n<APIItem name=\"extendEditorApi\" type=\"(api: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\">\nExtends the editor's API with plugin-specific methods.\n\n```ts\n(api: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\n```\n</APIItem>\n\n<APIItem name=\"extendTransforms\" type=\"(transforms: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\">\nExtends the plugin's transforms.\n\n```ts\n(transforms: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\n```\n</APIItem>\n\n<APIItem name=\"extendEditorTransforms\" type=\"(transforms: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\">\nExtends the editor's transforms with plugin-specific methods.\n\n```ts\n(transforms: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin\n```\n</APIItem>\n\n<APIItem name=\"extendSelectors\" type=\"(options: (ctx: PlatePluginContext) => Record<string, any>) => PlatePlugin\">\nExtends the plugin with selectors.\n\n```ts\n(options: (ctx: PlatePluginContext) => Record<string, any>) => PlatePlugin\n```\n</APIItem>\n</APIMethods>\n</API>\n\n## Plugin Context\n\n<API name=\"Context\">\n<APIAttributes>\n<APIItem name=\"editor\" type=\"PlateEditor\">\nThe current editor instance.\n</APIItem>\n<APIItem name=\"plugin\" type=\"EditorPlatePlugin<C>\">\nThe current plugin instance.\n</APIItem>\n<APIItem name=\"getOption\" type=\"function\">\nFunction to get a specific option value.\n</APIItem>\n<APIItem name=\"getOptions\" type=\"function\">\nFunction to get all options for the plugin.\n</APIItem>\n<APIItem name=\"setOption\" type=\"function\">\nFunction to set a specific option value.\n</APIItem>\n<APIItem name=\"setOptions\" type=\"function\">\nFunction to set multiple options.\n</APIItem>\n</APIAttributes>\n</API>\n\nFor more detailed information on specific aspects of Plate plugins, refer to the individual guides on [Plugin Configuration](/docs/plugin), [Plugin Methods](/docs/plugin-methods), [Plugin Context](/docs/plugin-context), [Plugin Components](/docs/plugin-components), and [Plugin Shortcuts](/docs/plugin-shortcuts).\n\n## Generic Types\n\n<API name=\"GenericTypes\">\n<APIAttributes>\n<APIItem name=\"C\" type=\"AnyPluginConfig = PluginConfig\">\nRepresents the plugin configuration. This type extends `PluginConfig` which includes `key`, `options`, `api`, and `transforms`.\n</APIItem>\n</APIAttributes>\n</API>\n\nUsage example:\n\n```typescript\ntype MyPluginConfig = PluginConfig<\n  'myPlugin',\n  { customOption: boolean },\n  { getData: () => string },\n  { customTransform: () => void }\n>;\n\nconst MyPlugin = createPlatePlugin<MyPluginConfig>({\n  key: 'myPlugin',\n  // plugin implementation\n});\n```\n",
      "type": "registry:file",
      "target": "content/docs/plate/api/core/plate-plugin.mdx"
    }
  ],
  "type": "registry:file"
}