Plate
PlateEditorsTemplates
GitHub16kGitHub
DiscordDiscord
  • Plate
  • Editor API
  • Editor Transforms
  • Node
  • Element
  • Text
  • Path
  • Point
  • Range
  • Location
  • Anchor
  • Selection
  • Document Change
  • DOM API
  • React Hooks
  • Plate Core
    • Plate Components
    • Plate Editor
    • Plate Plugin
    • Editor Context
    • Plate Controller
  • Plate Utils
  • Resizable

Plate Editor API

PreviousNext

Editor creation, plugins, and React hooks from platejs.

API

BlockInsertOptions

Placement options for feature commands that insert whole blocks. Import the type from platejs when declaring a public command boundary. It takes one of at, after and before, and replaceEmpty only with after or no placement. The type refuses other combinations, and passing one throws.

Document ChangePlate Components

On This Page

APIBlockInsertOptionscreateEditorEditorApplicationSchemadefineDocumentMigrationsmigrateDocumentdefinePlugintoReactPluginuseCreateEditoruseEditorRootElementuseEditorScrollElementuseEditoruseOptionalEditoruseEditorSelectoruseEditorStateuseEditorComposinguseEditorReadOnlyuseEditorMounteduseEditorHasSelectionuseEditorSelectionEditorProvideruseSelectionFragmentPropusePathusePluginStoreuseElementCore pluginsDebugPluginElementIdPluginElementStatePluginDOM operationsHistoryPluginInlineVoidPluginHtmlPluginParagraphPluginComponents<EditorElement><EditorLeaf><EditorText>
Build your editor
Production-ready AI template and reusable components.
Get all-access
  • at: the path to insert at, a slot among its parent's children.
  • before: the block to insert before.
  • after: the block to insert after. Without at, after and before, the insert lands after the caret's block, or after the container that hides what follows it, such as a closed Details for its title.
  • replaceEmpty: replace the empty, writable source text block the blocks land after. Structural and atomic blocks, and an empty block that is not block content, such as a Details title, remain intact.
  • select: select the inserted content.
  • A block insert command returns false and changes nothing when the block does not fit where it would land, such as in a parent that already holds as many children as it allows. An upsert returns true when it reuses a matching empty block.

    createEditor

    Creates a new Editor with the supplied plugins and configuration. To render an editor you already have, pass it to EditorRoot. An option this table does not list throws.

    OptionsCreateEditorOptions

      Unique identifier for the editor.

      An array of editor plugins.

      Synchronous initial document, persisted { document, schema, selection? } envelope, or primary-root array. A document holds only children, roots, meta and records; pass a selection through selection. Use the callback when decoding needs the compiled editor model. Load remote data before constructing the editor.

      Select the editor after initialization.

      • Default: false
      • true | 'end': Select the end of the editor
      • false: Do not select anything
      • 'start': Select the start of the editor

      Enable mark and element affinity.

      • Default: true

      Maximum character count for user-facing text, fragment, and node insertions.

      Configuration for the built-in navigation feedback plugin.

      Initial selection for the editor.

      Initial model selection, used when selection is not set.

      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.

      • Default: false

      When true, skips initialValue, selection and normalization, such as when Yjs collaboration manages the document.

      • Default: false

      Receives errors that the editor catches so they cannot stop it: throws from plugin lifecycle observers, history replays and their handlers, data-transfer formats, external text adapters and pagination, and reports from the renderElement check.

      • Default: each error goes to reportError as one Error whose message names its source, with the original error as cause. Where reportError does not exist, it goes to console.error.

      API 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.

      Initial state of the editor's root plugin.

      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.

      The user this editor writes and comments as, recorded as the author of authored changes and read back as editor.userId. Without it, the editor writes as the local user, 'local'. Pass one whenever more than one person writes the document. It stays fixed for the editor's life, and a userId that contains a NUL character throws.

    ReturnsEditor

      An editor instance with plugins and config applied.

    For more details on editor configuration, refer to the Editor Configuration guide.

    EditorApplicationSchema

    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.

    defineDocumentMigrations

    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.

    Each step receives { document, legacy, from, to, target } and returns { document, legacy?, mapSelection? }. document holds only children, meta, roots and records, and its type refuses any other key. legacy holds the stored document's other top-level fields until a step lifts them; a step that omits legacy passes it on unchanged.

    migrateDocument

    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. With an explicit source, the runner reads any input as a raw document. The runner rejects a different lineage, a future source, fingerprint drift, non-JSON data, invalid step results, a stored top-level field no step lifted, and malformed final output.

    definePlugin

    Creates a React Plate plugin from one inferred definition.

    Parameters

      The stable capability name used for plugin lookup and API namespaces.

      The plugin definition. The factory infers its name, initial state, API, read and update methods, schema, dependencies, editor capabilities, and React fields from this object.

    ReturnsPlugin

      A new plugin instance.

    toReactPlugin

    Extends a BasePlugin to create a React Plugin.

    Parameters

      The base BasePlugin to be extended.

      React-specific fields to add to the exact Base plugin definition.

    ReturnsPlugin

      A new plugin descriptor that preserves the exact Base definition and adds the supplied React fields.

    useCreateEditor

    Creates a memoized Plate editor for React components.

    Parameters

      Configuration options for creating the Plate editor. All options from createEditor are supported, plus:

      Additional dependencies for the useMemo hook.

      • Default: []

    ReturnsEditor | null

      A memoized Plate editor instance. Returns null if enabled is false.

    useEditorRootElement

    ReturnsHTMLElement | null

      The mounted editor root element.

    useEditorScrollElement

    ReturnsHTMLElement | null

      The element Plate uses as the editor scroll container.

    useEditor

    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

    useOptionalEditor(): Editor | null returns null without a provider or selected editor.

    useEditorSelector

    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

    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

    useEditorComposing(): boolean reads the selected view’s composition state.

    useEditorReadOnly

    useEditorReadOnly(): boolean reads the selected view’s current permission. Captured views become read-only after unmount; an empty controller is also read-only.

    useEditorMounted

    useEditorMounted(): boolean reports whether the selected view has mounted editable DOM.

    useEditorHasSelection

    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

    useEditorSelection(): Range | null returns the selected root’s text selection. Equal ranges do not trigger a rerender.

    EditorProvider

    <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.

    useSelectionFragmentProp

    Returns a prop value derived from the current selection fragment.

    OptionsGetSelectionFragmentOptions & GetFragmentPropOptions

      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'

    Returns

      A value derived from the fragment nodes, or undefined if no consistent value is found across the specified nodes.

    usePath

    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.

    Returns

      The current element path.

    usePluginStore

    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.

    Parameters

      The plugin whose editor-local store should be observed.

      A state key, named selector key, or selector callback.

      Arguments for a named selector. Selector callbacks instead accept { id?, equalityFn? } as the final options object.

    ReturnsT

      The selected field or derived value.
    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 }
    );

    useElement

    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.

    Parameters

      Plugin descriptor whose configured element provider and schema type should be inferred.

    ReturnsElementForDescriptor<TPlugin> | Element

      The current element. Throws when used outside the requested element provider.

    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();

    Core plugins

    DebugPlugin

    Provides debugging capabilities with configurable log levels and error handling.

    See Debugging for more details.

    ElementIdPlugin

    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") } },
          }),
        ],
      },
    });

    ElementStatePlugin

    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",
    
    
    
    
    

    DOM operations

    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.

    HistoryPlugin

    Enables undo and redo functionality for the editor.

    InlineVoidPlugin

    Manages inline and void elements in the editor.

    HtmlPlugin

    Enables HTML serialization and deserialization.

    ParagraphPlugin

    Provides paragraph formatting functionality.

    Components

    <EditorElement>

    Generic component for rendering an element.

    Props

      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'

    <EditorLeaf>

    Generic component for rendering a leaf.

    Props

      The CSS class to apply to the component.

      The editor context.

      Necessary for rendering the node children.

      The leaf node.

      The text node.

      Attributes of the leaf to be spread on the top-level element.

      The component type to render as. - Default: 'span'

    <EditorText>

    Generic component for rendering text.

    Props

      The CSS class to apply to the component.

      The text node.

      Attributes of the text to be spread on the top-level element.

      Necessary for rendering the node children.

      The component type to render as. - Default: 'span'

    target: target.
    group
    (
    "block"
    ),
    }),
    },
    },
    });