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.
| Surface | Owner | Notes |
|---|---|---|
PlateEditor | @platejs/core/react | React editor type with Plate plugin APIs, transaction groups, lifecycle/DOM events, renders, and hooks. |
BaseEditor | @platejs/core | Non-React editor type used by server-side and static editor paths. |
| Plite primitives | @platejs/plite | children, selection, operations, core api, and the transaction/update runtime. |
| Core plugins | @platejs/core | Debugging, HTML parsing, product codecs, length, node id, history, input rules, and base paragraph behavior. |
| React core plugins | @platejs/core/react | React 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.
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.
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.
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.
| State | Read path | Set by |
|---|---|---|
| composition | editor.api.react.isComposing() | Plite React composition runtime. |
| focus | editor.api.react.isFocused() | Plite React focus runtime. |
| read-only | editor.read.view.isReadOnly() or editor.api.react.isReadOnly() | createPlateEditor, <Plate>, and <PlateContent>. |
| Field | Type | Notes |
|---|---|---|
userId | string | null | undefined | Collaborative identity passed through editor options. |
isNormalizing | boolean | undefined | true while Plate applies initial-value normalization. |
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.
editor.api.table.getColumnCount();
// Generic package code with an exact descriptor:
editor.plugin(TablePlugin).api.getColumnCount();editor.api.table.getColumnCount();
// Generic package code with an exact descriptor:
editor.plugin(TablePlugin).api.getColumnCount();import { FindReplacePlugin } from "@platejs/find-replace";
const findReplace = editor.plugin(FindReplacePlugin);
const search = findReplace.store.get("search");
findReplace.store.set({ search: search.trim() });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.
| Helper | Type | Use 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).installed | boolean | Check installation before reading another portal field when the plugin is optional. |
plugin(plugin).api | InferOwnApi<DefinitionOf<P>> | Call the same plugin API from generic or exact-descriptor code. |
plugin(plugin).read | InferOwnRead<DefinitionOf<P>> | Run one plugin-owned read against current editor state. |
plugin(plugin).update | InferOwnUpdate<DefinitionOf<P>> | Run one plugin-owned update command. |
plugin(plugin).store.get(key, ...args) | (key, ...args) => value | Read 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) => void | Merge state fields. |
plugin(plugin).store.set(recipe) | (draft) => void | Update state through a draft recipe. |
plugin(plugin).name, .inject, .render, .initialState | Resolved descriptor fields | Read compiled descriptor fields directly after overrides and configuration. |
plugin(plugin) | (plugin: PluginReference | string) => AnyBasePluginPortal | Open 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.
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.
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." }],
},
],
});
}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:
| Step | Behavior |
|---|---|
| Runtime state | Preserves Plite editor.id and initializes runtime.userId. |
| Plugin access | Publishes installed APIs under editor.api[name] and installs descriptor-or-name plugin(...) portals. |
| Core plugins | Resolves core plugins, replaces core plugins with custom plugins that share the same name, and resolves the root plugin. |
| Components | Merges components into root-plugin component overrides. |
| Normalization guard | Wraps normalizeNode so editor.api.shouldNormalizeNode(entry) can skip a normalization pass. |
| Initial value | Initializes 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.
These APIs exist on every Plate editor because core plugins are always resolved before user plugins.
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.
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.
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.
Some core behavior is exposed by routing browser/editor events into the Plite transaction runtime rather than by adding public editor methods.
| Surface | Effect |
|---|---|
| Product codec registry | Compiles 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 events | Emits committed node and text change contexts through Plate on.nodeChange and on.textChange. |
| Plite React runtime | Handles editable keyboard, composition, focus, read-only, DOM selection export, and decoration refresh behavior. |
HtmlPlugin | Registers the text/html parser path and owns HTML element conversion through editor.api.html.deserialize. |
BaseParagraphPlugin | Registers the default paragraph element under name paragraph and maps HTML <p> elements, excluding code-font paragraphs. |
Use PlateEditor<typeof Kit> when another module needs the exact editor type.
The installed plugin schema supplies the value type.
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>;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>;| Type | Purpose |
|---|---|
PlateEditor | Broad 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. |
Plate, PlateContent, PlateView, and component-layer runtime effects.editor.update.