From zbeyens. The source code is available on GitHub.

Plate
PlatePliteEditorsTemplates
GitHub16kGitHub
DiscordDiscord
  • Plate
  • Plitev42
    • Editor API
    • Editor Transforms
    • Node
    • Element
    • Text
    • Path
    • Point
    • Range
    • Location
    • Location Ref
    • Document Change
  • Plate Core
    • Plate Components
    • Plate Editor
    • Plate Plugin
    • Plate Store
    • Plate Controller
  • Plate Utils
  • React Utils
  • cn
  • Floating
  • Resizable

Plate Editor

PreviousNext

API reference for the Plate editor runtime.

PlateEditor is the React editor type returned by createPlateEditor, usePlateEditor, and withPlate. It extends the base Plite editor with typed plugin portals, typed api, typed editor.update() transactions, DOM services, and editor-local plugin stores.

Ownership

SurfaceOwnerNotes
PlateEditor@platejs/core/reactReact editor type with Plate plugin APIs, transaction groups, lifecycle/DOM events, renders, and hooks.
Plate ComponentsPlate Plugin

On This Page

OwnershipEditor ShapeRuntime StatePlugin AccessInitializationCore APIsCore TransactionsPlugin Pipeline EffectsType HelpersRelated APIs
Build your editor
Production-ready AI template and reusable components.
Get all-access
BaseEditor@platejs/coreNon-React editor type used by server-side and static editor paths.
Plite primitives@platejs/plitechildren, selection, operations, core api, and the transaction/update runtime.
Core plugins@platejs/coreDebugging, HTML parsing, product codecs, length, node id, history, input rules, and base paragraph behavior.
React core plugins@platejs/core/reactReact extension, DOM integration, event editor, navigation feedback, and React paragraph plugin.

Use PlateEditor when a page or component runs inside React. Use BaseEditor when you need the headless editor from createBaseEditor.

Editor Shape

The editor is still a Plite editor. Plate adds typed plugin access, DOM services, and a small set of Plate runtime flags on top of that shape.

Attributes

    Unique editor instance id. withPlite uses the provided id, an existing editor id, or nanoid().

    Current document value.

    Current Plite selection.

    Operations applied since Plite last flushed the editor.

    Core Plite APIs, explicit editor-wide APIs, and installed plugin APIs inferred under their plugin names.

    Transaction entrypoint for document, selection, history, and plugin commands.

    Return the descriptor-scoped portal for a plugin's API, update commands, type, and store.

    Runtime DOM state owned by the editor instance.

    Public Plate runtime-instance and lifecycle state. Compiled plugin registries stay private to Plate.

Runtime State

React and DOM runtime state is read through Plite runtime APIs. Plate exposes only editor identity and lifecycle fields on editor.runtime; compiled plugin registries are private implementation data.

StateRead pathSet by
compositioneditor.api.react.isComposing()Plite React composition runtime.
focuseditor.api.react.isFocused()Plite React focus runtime.
read-onlyeditor.read.view.isReadOnly() or editor.api.react.isReadOnly()createPlateEditor, <Plate>, and <PlateContent>.
FieldTypeNotes
userIdstring | null | undefinedCollaborative identity passed through editor options.
isNormalizingboolean | undefinedtrue while Plate applies initial-value normalization.

Plugin Access

Use editor.api.<name> for installed plugin services on a concrete editor. Use editor.read.<name> for snapshot-bound plugin queries. Pass the descriptor to editor.plugin(plugin) when generic code needs the exact plugin API, update commands, name, or store. The root and scoped API paths reference the same immutable object.

Plugin API access
editor.api.table.getColumnCount();
 
// Generic package code with an exact descriptor:
editor.plugin(TablePlugin).api.getColumnCount();
Plugin API access
editor.api.table.getColumnCount();
 
// Generic package code with an exact descriptor:
editor.plugin(TablePlugin).api.getColumnCount();
Plugin state access
import { FindReplacePlugin } from "@platejs/find-replace";
 
const findReplace = editor.plugin(FindReplacePlugin);
 
const search = findReplace.store.get("search");
findReplace.store.set({ search: search.trim() });
Plugin state access
import { FindReplacePlugin } from "@platejs/find-replace";
 
const findReplace = editor.plugin(FindReplacePlugin);
 
const search = findReplace.store.get("search");
findReplace.store.set({ search: search.trim() });

In the table below, P is the exact plugin descriptor type and DefinitionOf<P> is its normalized public definition.

HelperTypeUse it for
api[name]InferOwnApi<DefinitionOf<P>>Call an installed plugin's queries and services from a concrete inferred editor.
plugin(plugin)<P extends AnyBasePlugin & PluginReference>(plugin: P) => BasePluginPortal<DefinitionOf<P>>Open a typed consumer portal to the exact plugin descriptor.
plugin(plugin).installedbooleanCheck installation before reading another portal field when the plugin is optional.
plugin(plugin).apiInferOwnApi<DefinitionOf<P>>Call the same plugin API from generic or exact-descriptor code.
plugin(plugin).readInferOwnRead<DefinitionOf<P>>Run one plugin-owned read against current editor state.
plugin(plugin).updateInferOwnUpdate<DefinitionOf<P>>Run one plugin-owned update command.
plugin(plugin).store.get(key, ...args)(key, ...args) => valueRead one state field or named selector result.
plugin(plugin).store.get()() => InferPluginStoreState<DefinitionOf<P>>Read the complete current plugin state.
plugin(plugin).store.set(partial)(partial) => voidMerge state fields.
plugin(plugin).store.set(recipe)(draft) => voidUpdate state through a draft recipe.
plugin(plugin).name, .inject, .render, .initialStateResolved descriptor fieldsRead compiled descriptor fields directly after overrides and configuration.
plugin(plugin)(plugin: PluginReference | string) => AnyBasePluginPortalOpen an erased portal for a descriptor or dynamic name; concrete descriptors use the exact overload above.

In React, subscribe with usePluginStore(plugin, key) or usePluginStore(plugin, selector) instead of reading a portal during render. useEditorPlugin accepts the same descriptor-or-runtime-name inputs. Runtime names are for dynamic values and family-agnostic slots that accept whichever installed descriptor owns the name. They return erased portals; check .installed before any other field when absence is valid.

Initialization

withPlate wraps withPlite with React defaults. It creates each plugin's editor-local store from initialState and prepends the React core plugins before user plugins.

Create a typed editor
import { usePlateEditor } from "platejs/react";
import { BoldPlugin } from "@platejs/basic-nodes/react";
 
export function useBasicEditor() {
  return usePlateEditor({
    plugins: [BoldPlugin],
    initialValue: [
      {
        type: "paragraph",
        children: [{ text: "Bold text is ready." }],
      },
    ],
  });
}
Create a typed editor
import { usePlateEditor } from "platejs/react";
import { BoldPlugin } from "@platejs/basic-nodes/react";
 
export function useBasicEditor() {
  return usePlateEditor({
    plugins: [BoldPlugin],
    initialValue: [
      {
        type: "paragraph",
        children: [{ text: "Bold text is ready." }],
      },
    ],
  });
}

withPlite does the lower-level setup:

StepBehavior
Runtime statePreserves Plite editor.id and initializes runtime.userId.
Plugin accessPublishes installed APIs under editor.api[name] and installs descriptor-or-name plugin(...) portals.
Core pluginsResolves core plugins, replaces core plugins with custom plugins that share the same name, and resolves the root plugin.
ComponentsMerges components into root-plugin component overrides.
Normalization guardWraps normalizeNode so editor.api.shouldNormalizeNode(entry) can skip a normalization pass.
Initial valueInitializes the value and selection through the runtime update path unless skipInitialization is true.

initialValue accepts a Plate value or a synchronous function that returns one. Load remote data before constructing the editor. Use the callback form when a decoder needs the compiled plugin model.

Core APIs

These APIs exist on every Plate editor because core plugins are always resolved before user plugins.

Methods

    Log a debug message when debug logging is enabled.

    Log an info message when the configured log level allows it.

    Log a warning when the configured log level allows it.

    Throw a PlateError by default in development. Configure DebugPlugin to change logging or throwErrors.

    Deserialize an HTML element into Plate nodes. The HTML parser plugin calls this for text/html paste data.

    Refresh React decorations after an external state change.

    Read the current navigation feedback target and clear it if the stored target no longer resolves.

    Clear the current navigation feedback target.

    Check whether a path matches the active navigation feedback target.

Core Transactions

Mutations run through editor.update. Core Plite commands live on the transaction object, and plugins contribute their keyed commands through the constructor's update field.

Transforms

    Replace primary children, named roots, persisted meta, and optionally the selection through one configured Plite update.

    Insert a node or fragment through the Plite node transaction group.

    Update matching nodes through the Plite node transaction group.

    Toggle an inline mark through the Plite mark transaction group.

    Update the current selection through the Plite selection transaction group.

    Clear navigation feedback state.

    Store a target temporarily so components can render navigation feedback.

    Navigate to a target and flash it through the navigation feedback plugin.

Plugin Pipeline Effects

Some core behavior is exposed by routing browser/editor events into the Plite transaction runtime rather than by adding public editor methods.

SurfaceEffect
Product codec registryCompiles constructor codec declarations created by context-bound defineCodecs(map) or defineCodecs(TargetPlugin, map), then delegates exact ContentSlice decoding and encoding to the generic clipboard runtime.
Plite change eventsEmits committed node and text change contexts through Plate on.nodeChange and on.textChange.
Plite React runtimeHandles editable keyboard, composition, focus, read-only, DOM selection export, and decoration refresh behavior.
HtmlPluginRegisters the text/html parser path and owns HTML element conversion through editor.api.html.deserialize.
BaseParagraphPluginRegisters the default paragraph element under name paragraph and maps HTML <p> elements, excluding code-font paragraphs.

Type Helpers

Use PlateEditor<typeof Kit> when another module needs the exact editor type. The installed plugin schema supplies the value type.

Typed editor helper
import type { PlateEditor } from "platejs/react";
import type { ValueOf } from "platejs";
import { BoldPlugin } from "@platejs/basic-nodes/react";
 
const BasicKit = [BoldPlugin] as const;
 
type BasicEditor = PlateEditor<typeof BasicKit>;
type BasicValue = ValueOf<BasicEditor>;
Typed editor helper
import type { PlateEditor } from "platejs/react";
import type { ValueOf } from "platejs";
import { BoldPlugin } from "@platejs/basic-nodes/react";
 
const BasicKit = [BoldPlugin] as const;
 
type BasicEditor = PlateEditor<typeof BasicKit>;
type BasicValue = ValueOf<BasicEditor>;
TypePurpose
PlateEditorBroad editor type for framework boundaries.
PlateEditor<typeof Kit>Exact editor type derived from an installed plugin tuple.
ValueOf<PlateEditorType>Document value derived from that editor's compiled schema.

Related APIs

  • Plate components covers Plate, PlateContent, PlateView, and component-layer runtime effects.
  • PlateController covers active, primary, and fallback editor lookup.
  • Plate plugin covers plugin definitions, methods, state, events, and render hooks.
  • Controlled Value covers React-owned value patterns around editor.update.