docs/api/core/plate-plugin.mdx
Plate plugins are objects passed to Plate plugins prop.
type OnNodeChange = (ctx: PlatePluginContext & {
node: Descendant;
operation: NodeOperation;
prevNode: Descendant;
}) => HandlerReturnType;
Parameters:
node: The node after the operationoperation: The node operation that occurredprevNode: The node before the operationNote: For insert_node and remove_node operations, both node and prevNode contain the same value to avoid null cases.
</APISubListItem>
<APISubListItem parent="handlers" name="onTextChange" type="OnTextChange" optional>
Called whenever a text operation occurs (insert or remove text).
type OnTextChange = (ctx: PlatePluginContext & {
node: Descendant;
operation: TextOperation;
prevText: string;
text: string;
}) => HandlerReturnType;
Parameters:
node: The parent node containing the text that changedoperation: The text operation that occurred (insert_text or remove_text)prevText: The text content before the operationtext: The text content after the operation
</APISubListItem>
[ParagraphPlugin.key]
</APISubListItem>
true
</APISubListItem>
'default': Uses Slate's default behavior
'directional': Selection affinity is determined by the direction of cursor movement. Maintains inward or outward affinity based on approach
'outward': Forces outward affinity. Typing at the edge of a mark will not apply the mark to new text
'hard': Creates a 'hard' edge that requires two key presses to move across. Uses offset-based navigation
Default: undefined (Slate's default behavior)
true
</APISubListItem>
Used by exit break functionality to determine appropriate exit points in nested structures. See Exit Break.
false
</APISubListItem>
'default': Default behavior'reset': Reset block to default paragraph type'exit': Exit the current block'deleteExit': Delete backward then exit
</APISubListItem>
'default': Default behavior'exit': Exit the current block'deleteExit': Delete backward then exit
</APISubListItem>
'default': Default behavior'exit': Exit the current block'lineBreak': Insert newline character'deleteExit': Delete backward then exit
</APISubListItem>
'default': Default behavior'reset': Reset block to default paragraph type
</APISubListItem>
'default': Default behavior'reset': Reset block to default paragraph type
</APISubListItem>
Default: type === node.type
Example: matchRules: ({ node }) => Boolean(node.listStyleType)
Example: List plugin sets match: ({ node }) => !!node.listStyleType to override paragraph behavior when the paragraph is a list item.
false
</APISubListItem>
false
</APISubListItem>
plugin.key
</APISubListItem>
'div' for elements, 'span' for leaves100
</APIItem>
extendEditor: ({ editor }) => {
// Example: Integrating a legacy Slate plugin
return withYjs(editor);
}
Can be either a boolean or an object configuration:
type EditOnlyConfig = {
render?: boolean; // default: true
handlers?: boolean; // default: true
inject?: boolean; // default: true
normalizeInitialValue?: boolean; // default: false
}
When set to true (boolean):
render, handlers, and inject.nodeProps are only active when editor is not read-onlynormalizeInitialValue remains active regardless of read-only stateWhen set to an object:
true) except normalizeInitialValue which defaults to always active (false)false to make it always active regardless of read-only statenormalizeInitialValue, set to true to make it edit-onlyExamples:
// All features (except normalizeInitialValue) are edit-only
editOnly: true
// normalizeInitialValue is edit-only, others remain edit-only by default
editOnly: { normalizeInitialValue: true }
// render is always active, others follow default behavior
editOnly: { render: false }
(config: PlatePluginConfig<C['key'], InferOptions<C>, InferApi<C>, InferTransforms<C>> | ((ctx: PlatePluginContext<C>) => PlatePluginConfig<C['key'], InferOptions<C>, InferApi<C>, InferTransforms<C>>)) => PlatePlugin<C>
(extendConfig: Partial<PlatePlugin> | ((ctx: PlatePluginContext<AnyPluginConfig>) => Partial<PlatePlugin>)) => PlatePlugin
(key: string, extendConfig: Partial<PlatePlugin> | ((ctx: PlatePluginContext<AnyPluginConfig>) => Partial<PlatePlugin>)) => PlatePlugin
(component: NodeComponent) => PlatePlugin<C>
overrideEditor(({ editor, tf: { deleteForward }, api: { isInline } }) => ({
transforms: {
// Override transforms
deleteForward(options) {
deleteForward(options);
},
},
api: {
// Override API methods
isInline(element) {
return isInline(element);
},
},
})) => PlatePlugin<C>
(api: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin
(api: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin
(transforms: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin
(transforms: (ctx: PlatePluginContext) => Record<string, Function>) => PlatePlugin
(options: (ctx: PlatePluginContext) => Record<string, any>) => PlatePlugin
For more detailed information on specific aspects of Plate plugins, refer to the individual guides on Plugin Configuration, Plugin Methods, Plugin Context, Plugin Components, and Plugin Shortcuts.
Usage example:
type MyPluginConfig = PluginConfig<
'myPlugin',
{ customOption: boolean },
{ getData: () => string },
{ customTransform: () => void }
>;
const MyPlugin = createPlatePlugin<MyPluginConfig>({
key: 'myPlugin',
// plugin implementation
});