BlockInsertOptionsPlacement options for feature commands that insert whole blocks. Import the
type from platejs when declaring a public command boundary.
at: an explicit insertion location.after: a live source block target; omit at when using it.replaceEmpty: replace the empty, writable source text block when inserting
after it. Structural and atomic blocks remain intact.select: select the inserted content.Creates an Editor with the supplied plugins and configuration.
Unique identifier for the editor.
An array of editor plugins.
Synchronous initial document, persisted
{ document, schema, selection? } envelope, or primary-root array. Use the
callback when decoding needs the compiled editor model. Load remote data
before constructing the editor.
Select the editor after initialization.
falsetrue | 'end': Select the end of the editorfalse: Do not select anything'start': Select the start of the editorMaximum character count for user-facing text, fragment, and node insertions.
Configuration for the built-in navigation feedback plugin.
Initial selection for the editor.
Application schema policy and optional named persisted lineage. Omit root
for the standard paragraph root. Supply id and version together.
When true, it normalizes the initialValue passed to the editor.
falseAPI methods for the editor.
Decoration function for the editor.
Lifecycle and DOM events. Child names are prefixless, such as commit,
nodeChange, keyDown, and paste.
Injection configuration for the editor.
Additional options for the editor.
Override configuration for the editor.
Editor read-only initial state. For dynamic value, use
EditorRoot.readOnly prop.
Render functions for the editor.
Keyboard shortcuts for the editor.
Transform functions for the editor.
For more details on editor configuration, refer to the Editor Configuration guide.
Defines application-owned schema policy. Its optional fields are:
root: primary-root SchemaContent with an explicit positive integer
min. Descriptor sources must match the installed plugin family. The first
source in schema.content.elements is the default.overrides: final application overrides for installed element schemas and
existing property targets.properties: application-owned schema properties.id and version: a paired persisted lineage. Supply both or neither.Omitting root preserves Plate's standard minimum-one paragraph grammar. Root
grammar participates in the compiled fingerprint and generated value contract.
Defines one target-version migration chain for a named application schema. Each numeric key is the schema version produced by that step.
import { defineDocumentMigrations } from "platejs/migrations";
import { fingerprint as v1Fingerprint } from "./migrations/v2-add-section/from";
import { fingerprint as v2Fingerprint } from "./migrations/v3-add-caption/from";
const migrations = defineDocumentMigrations({
plugins: EditorKit,
schema: EditorSchema,
sourceFingerprints: {
1: v1Fingerprint,
2: v2Fingerprint,
},
steps: {
2: migrateDocumentV2,
3: migrateDocumentV3,
},
});import { defineDocumentMigrations } from "platejs/migrations";
import { fingerprint as v1Fingerprint } from "./migrations/v2-add-section/from";
import { fingerprint as v2Fingerprint } from "./migrations/v3-add-caption/from";
const migrations = defineDocumentMigrations({
plugins: EditorKit,
schema: EditorSchema,
sourceFingerprints: {
1: v1Fingerprint,
2: v2Fingerprint,
},
steps: {
2: migrateDocumentV2,
3: migrateDocumentV3,
},
});sourceFingerprints binds every supported historical envelope version to its
generated schema fingerprint. The definition compiles plugins and schema
once into the immutable current target used by every step. Plate rejects
missing intermediate steps and historical identity drift.
Converts one complete document into an exact current persisted envelope. The operation does not create or publish an editor.
import { migrateDocument } from "platejs/migrations";
const { output, applied, source } = migrateDocument(persisted, {
migrations: EditorMigrations,
});
const imported = migrateDocument(legacyDocument, {
migrations: EditorMigrations,
source: 1,
});import { migrateDocument } from "platejs/migrations";
const { output, applied, source } = migrateDocument(persisted, {
migrations: EditorMigrations,
});
const imported = migrateDocument(legacyDocument, {
migrations: EditorMigrations,
source: 1,
});output contains exactly { document, schema, selection? } and can be saved or
passed to createEditor. applied lists the destination versions that ran, and
source is the validated source version. Raw documents require source: number
or source: 'current'; persisted envelopes carry their own source identity. The
runner rejects a different lineage, a future source, fingerprint drift,
non-JSON data, invalid step results, and malformed final output.
Creates a React Plate plugin from one inferred definition.
Extends a BasePlugin to create a React Plugin.
Creates a memoized Plate editor for React components.
useEditor(): Editor returns the nearest provider’s selected editor and throws when no target exists. It rerenders when the provider changes targets without subscribing to document commits. Inside EditorContent, it binds commands to that mount’s root, DOM, and permissions.
useOptionalEditor(): Editor | null returns null without a provider or selected editor.
useEditorSelector(selector, options?) derives a value from the selected editor and rerenders when the result changes. The selector receives (editor, previous?); options include equalityFn and shouldUpdate.
useEditorState(selector, options?) subscribes to a value derived from immutable editor state and returns the selector’s inferred result. For a concrete editor type, use useEditorRuntimeState(editor, selector, options?).
useEditorComposing(): boolean reads the selected view’s composition state.
useEditorReadOnly(): boolean reads the selected view’s current permission. Captured views become read-only after unmount; an empty controller is also read-only.
useEditorMounted(): boolean reports whether the selected view has mounted editable DOM.
useEditorHasSelection(): boolean reports a text selection in the selected root, including a caret. It rerenders only when presence changes and does not report DOM focus.
useEditorSelection(): Range | null returns the selected root’s text selection. Equal ranges do not trigger a rerender.
<EditorProvider editor={editor}> binds descendant controls to an existing editor; editor={null} represents no target. It creates no editable view.
See Editor Context and Plate Controller.
Returns a prop value derived from the current selection fragment.
The key of the property to extract from each node.
The default value to return if no valid prop is found.
Custom function to extract the prop value from a node.
Determines how to traverse the fragment:
'all': Check both block and text nodes
'block': Only check block nodes
'text': Only check text nodes
Default: 'block'
Get the live path of the closest element and throw when the matching provider is absent. Pass a plugin descriptor to select an owning element provider.
Subscribe to a plugin state field, named selector, or selector callback inside
<EditorRoot>.
Pass the plugin descriptor itself—not a { name } object. The descriptor carries
the state fields, selector arguments, and return types, so no generic arguments
are needed.
const value = usePluginStore(plugin, "value");
const doubleValue = usePluginStore(plugin, "doubleValue", 2);
const state = usePluginStore(plugin, (state) => state);
const pair = usePluginStore(
plugin,
(state) => [state.value, state.label] as const,
{ equalityFn: shallow }
);const value = usePluginStore(plugin, "value");
const doubleValue = usePluginStore(plugin, "doubleValue", 2);
const state = usePluginStore(plugin, (state) => state);
const pair = usePluginStore(
plugin,
(state) => [state.value, state.label] as const,
{ equalityFn: shallow }
);Get the current element and throw when the matching provider is absent. Pass a
plugin descriptor for configured schema inference. Call it without a descriptor
only when deliberately working with the erased Element shape.
import { BlockquotePlugin } from "platejs/react";
import { useElement } from "platejs/react";
const quote = useElement(BlockquotePlugin);
const generic = useElement();import { BlockquotePlugin } from "platejs/react";
import { useElement } from "platejs/react";
const quote = useElement(BlockquotePlugin);
const generic = useElement();Provides debugging capabilities with configurable log levels and error handling.
See Debugging for more details.
Adds persisted string IDs to every block and inline element. It is opt-in and never assigns IDs to text nodes.
import { ElementIdPlugin, schema, target } from "platejs";
import { createEditor } from "platejs/react";
const editor = createEditor({
plugins: [ElementIdPlugin],
});
const elementId = editor.plugin(ElementIdPlugin);
const key = editor.key(element);
const id = elementId.read.id(key);
const entry = id ? elementId.read.entry(id) : undefined;import { ElementIdPlugin, schema, target } from "platejs";
import { createEditor } from "platejs/react";
const editor = createEditor({
plugins: [ElementIdPlugin],
});
const elementId = editor.plugin(ElementIdPlugin);
const key = editor.key(element);
const id = elementId.read.id(key);
const entry = id ? elementId.read.entry(id) : undefined;Configure initialState.generateId to replace the default full-length
nanoid() generator. Include ElementIdPlugin in the target passed to
defineDocumentMigrations. Current-document admission fills missing IDs and
rejects duplicate IDs before the editor is created. A historical migration
step must convert numeric IDs or legacy property names and define the
application's collision policy.
The application schema can narrow the plugin-owned id target. Current
document admission generates and retains IDs only for elements that match the
compiled target.
const editor = createEditor({
plugins: [ElementIdPlugin],
schema: {
overrides: [
schema.override(ElementIdPlugin, {
properties: { id: { target: target.group("block") } },
}),
],
},
});const editor = createEditor({
plugins: [ElementIdPlugin],
schema: {
overrides: [
schema.override(ElementIdPlugin, {
properties: { id: { target: target.group("block") } },
}),
],
},
});Extend editor behavior.
ElementStatePlugin exposes
editor.plugin(ElementStatePlugin).api.isEmpty(element). It checks the
element's own props, not its text content. By default, only type and compiled
element properties declared with role: "metadata" are ignored; any other prop
means the element carries state. ElementIdPlugin declares its persisted ID
property as metadata.
const elementState = editor.plugin(ElementStatePlugin);
elementState.api.isEmpty({
children: [{ text: "" }],
type: "paragraph",
}); // true
elementState.api.isEmpty({
children: [{ text: "" }],
listType: "bulleted",
type: "paragraph",
}); // false
const CustomMetadataPlugin = definePlugin("customMetadata", {
schema: {
properties: {
customId: schema.elementProperty(property.string(), {
role: "metadata",
target: target.group("block"),
}),
},
},
});const elementState = editor.plugin(ElementStatePlugin);
elementState.api.isEmpty({
children: [{ text: "" }],
type: "paragraph",
}); // true
elementState.api.isEmpty({
children: [{ text: "" }],
listType: "bulleted",
type: "paragraph",
}); // false
const CustomMetadataPlugin = definePlugin("customMetadata", {
schema: {
properties: {
customId: schema.elementProperty(property.string(), {
role: "metadata",
Use editor.api.dom for DOM queries and focus, and editor.update.dom for
clipboard insertion and transaction-scoped auto-scroll. Editor construction
installs the DOM integration.
Enables undo and redo functionality for the editor.
Manages inline and void elements in the editor.
Enables HTML serialization and deserialization.
Provides paragraph formatting functionality.
Generic component for rendering an element.
The CSS class to apply to the component.
The editor instance. Also available using the strict useEditor hook.
The element node. Also available using useElement hook.
The path of the element in the editor tree. Also available using usePath
hook.
Attributes of the element to be spread on the top-level element.
Necessary for rendering the node children.
The component type to render as. - Default: 'div'
Generic component for rendering a leaf.
Generic component for rendering text.