PlateEditor is the React editor type returned by createPlateEditor, usePlateEditor, and withPlate. It extends the base Plite editor with plugin registries, typed api, typed editor.update() transactions, DOM state, metadata, and plugin option helpers.
Ownership
| Surface | Owner | Notes |
|---|---|---|
PlateEditor | @platejs/core/react | React editor type with Plate plugin APIs, transaction groups, handlers, 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, parser pipeline, 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.
Editor Shape
The editor is still a Plite editor. Plate adds typed plugin access, plugin metadata, DOM state, and option stores 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 plus APIs contributed by resolved Plate plugins.
Transaction entrypoint for document, selection, history, and plugin commands.
Resolved plugin map keyed by plugin key.
Runtime DOM state owned by the editor instance.
Runtime metadata and plugin caches built during plugin resolution.
Runtime State
React and DOM runtime state is read through Plite runtime APIs. Plate keeps plugin metadata on editor.runtime.
| 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>. |
editor.runtime carries plugin resolution output. Most application code reads this indirectly through helpers like getPlugin, getOptions, and render utilities.
| Field | Type | Notes |
|---|---|---|
key | string | Internal editor key. withPlite creates one with nanoid() when missing. |
uid | string | undefined | Stable id used by Plate containers across RSC and client hydration. |
userId | string | null | undefined | Collaborative identity passed through editor options. |
components | NodeComponents | Resolved node components keyed by plugin key. |
isFallback | boolean | false for normal editors. Fallback editors are created by the controller layer. |
pluginList | AnyEditorPlatePlugin[] | Ordered resolved plugin list. |
inputRules | ResolvedInputRulesMeta | Input-rule metadata built by the input-rules plugin. |
shortcuts | Shortcuts | Resolved shortcut metadata. |
pluginCache | object | Precomputed plugin key lists for render hooks, handlers, rules, nodes, decorators, and injection. |
Plugin Access
Use editor helpers when you need the resolved plugin instance or live plugin options. Read plugin APIs from editor.api; run plugin commands through editor.update.
import { ParagraphPlugin, useEditorPlugin } from 'platejs/react';
export function ParagraphType() {
const { editor } = useEditorPlugin(ParagraphPlugin);
return <span>{editor.getType(ParagraphPlugin.key)}</span>;
}import { ParagraphPlugin, useEditorPlugin } from 'platejs/react';
export function ParagraphType() {
const { editor } = useEditorPlugin(ParagraphPlugin);
return <span>{editor.getType(ParagraphPlugin.key)}</span>;
}| Helper | Type | Use it for |
|---|---|---|
getPlugin(plugin) | <C>(plugin: WithRequiredKey<C>) => EditorPlatePlugin<C> | Read the resolved plugin instance after overrides and configuration. |
getType(pluginKey) | (pluginKey: string) => string | Resolve the node type for a plugin key. |
getInjectProps(plugin) | (plugin) => InjectNodeProps | Read injected node props with default nodeKey and styleKey filled from the plugin type. |
getOptionsStore(plugin) | (plugin) => TStateApi | Read the plugin option store. |
getOptions(plugin) | (plugin) => InferOptions<C> | Read all current options for a plugin. |
getOption(plugin, key, ...args) | (plugin, key, ...args) => value | Read one option or selector result. Missing stored keys report through editor.api.debug.error. |
setOption(plugin, key, value) | (plugin, key, value) => void | Update one option in the plugin store. |
setOptions(plugin, options) | (plugin, partialOrRecipe) => void | Merge a partial object or run a mutative recipe against the plugin state. |
Initialization
withPlate wraps withPlite with React defaults. It uses createZustandStore for plugin option stores 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],
value: [
{
type: 'p',
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],
value: [
{
type: 'p',
children: [{ text: 'Bold text is ready.' }],
},
],
});
}withPlite does the lower-level setup:
| Step | Behavior |
|---|---|
| Runtime metadata | Preserves Plite editor.id and installs Plate plugin runtime state such as runtime.isFallback, runtime.userId, and plugin caches. |
| Helper methods | Installs getPlugin, getType, option helpers, and injection helpers. |
| Core plugins | Resolves core plugins, replaces core plugins with custom plugins that share the same key, 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. |
value accepts a Plate value, an HTML string, or a function that returns the value. onReady receives { editor, isAsync, value } after initialization completes.
Core APIs
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.
Core Transactions
Mutations run through editor.update. Core Plite commands live on the transaction object, and plugin commands are added by extendTx or extendTxGroup.
Replace the editor value, and optionally the selection, through a 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.
| Plugin | Effect |
|---|---|
ParserPlugin | Handles paste data and scans plugin parsers in reverse plugin order. Matching parsers transform data, deserialize a fragment, transform the fragment, and insert it. |
| Plite change events | Emits committed node and text change contexts so Plate handlers can receive previous and next node or text state. |
| Plite React runtime | Handles editable keyboard, composition, focus, read-only, DOM selection export, and decoration refresh behavior. |
| Editable metadata cleanup | Strips static _memo metadata from editable normalized values. |
HtmlPlugin | Registers the text/html parser path and delegates HTML elements to editor.api.html.deserialize. |
BaseParagraphPlugin | Registers the default paragraph element under key p and maps HTML <p> elements, excluding code-font paragraphs. |
Type Helpers
Use PlateEditor when you want an editor typed to a specific value and plugin union.
import type { PlateEditor } from 'platejs/react';
import type { Value } from 'platejs';
import { BoldPlugin } from '@platejs/basic-nodes/react';
type BasicEditor = PlateEditor<Value, typeof BoldPlugin>;import type { PlateEditor } from 'platejs/react';
import type { Value } from 'platejs';
import { BoldPlugin } from '@platejs/basic-nodes/react';
type BasicEditor = PlateEditor<Value, typeof BoldPlugin>;| Type | Purpose |
|---|---|
PlateEditor | Runtime editor type with the default Plate core plugin surface. |
PlateEditor<V, P> | Typed editor for a specific Value and plugin union. |
KeyofPlugins<T> | String key union for Plate core plugins plus the supplied plugin config union. |
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 configuration, methods, options, handlers, and render hooks.
- Controlled Value covers React-owned value patterns around
editor.update.