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 Components

PreviousNext

API reference for Plate React components.

Plate components connect a PlateEditor to React rendering. Use Plate and PlateContent for editable editors, PlateView for read-only static views, and the node primitives when writing custom plugin components.

Editable Editor

Plate owns the editor store. PlateContent renders the editable surface under that store.

components/editor.tsx
import { Plate, PlateContent, usePlateEditor } from "platejs/react";
 
export function Editor() {
  const editor =













Plate CorePlate Editor

On This Page

Editable EditorRead-Only ViewComponent MapRender PipelineNode PrimitivesNode SelectionAPI ReferencePlatePlateContentPlateViewPlateContainerRender Primitives
Build your editor
Production-ready AI template and reusable components.
Get all-access
usePlateEditor
({
initialValue: [
{
children: [{ text: "Start writing." }],
type: "paragraph",
},
],
});
return (
<Plate editor={editor}>
<PlateContent placeholder="Write..." />
</Plate>
);
}
components/editor.tsx
import { Plate, PlateContent, usePlateEditor } from "platejs/react";
 
export function Editor() {
  const editor = usePlateEditor({
    initialValue: [
      {
        children: [{ text: "Start writing." }],
        type: "paragraph",
      },
    ],
  });
 
  return (
    <Plate editor={editor}>
      <PlateContent placeholder="Write..." />
    </Plate>
  );
}
Provider required

PlateContent must render below Plate. useEditor() requires an active editor and throws otherwise. Use useActiveEditor() only in controller UI that intentionally handles null while no editor is active.

Read-Only View

Use PlateView with a static editor when you need rendered content and Plate copy behavior without an editable surface.

components/read-only-editor.tsx
import { PlateView, usePlateViewEditor } from "platejs/react";
 
const value = [
  {
    children: [{ text: "Published content." }],
    type: "paragraph",
  },
];
 
export function ReadOnlyEditor() {
  const editor = usePlateViewEditor({ initialValue: value });
 
  if (!editor) return null;
 
  return <PlateView editor={editor} />;
}
components/read-only-editor.tsx
import { PlateView, usePlateViewEditor } from "platejs/react";
 
const value = [
  {
    children: [{ text: "Published content." }],
    type: "paragraph",
  },
];
 
export function ReadOnlyEditor() {
  const editor = usePlateViewEditor({ initialValue: value });
 
  if (!editor) return null;
 
  return <PlateView editor={editor} />;
}

PlateView wraps PlateStatic. Its default onCopy writes Plate fragment data to the clipboard, unless you pass your own onCopy prop.

Component Map

ComponentUse For
PlateStore provider for one editor instance.
PlateContentEditable Plite surface with plugin on callbacks, decorators, renderers, hotkeys, and editor effects.
PlateViewStatic read-only rendering with Plate fragment copy support.
PlateContainerEditor container div plus beforeContainer and afterContainer plugin slots.
NodeSelectionHighlightHighlight overlays for selected selectable blocks.
NodeSelectionDragBlank-space pointer-drag selection and its drag rectangle.
PlitePlite provider wrapper used by PlateContent; also applies abovePlite plugin wrappers.
PlateElementDefault element renderer for block and inline elements.
PlateLeafDefault decorated text-leaf renderer.
PlateTextDefault text-node renderer for non-decoration leaf rendering.
PlateTestTest helper that creates or wraps an editor and renders PlateContent with test attributes.

Render Pipeline

PlateContent composes editable props directly from store renderers, its own render props, plugin decorators, and plugin DOM events.

StageSource
Plite providerPlite receives the editor instance and store callbacks.
Editable propsPlateContent pipes decorators, DOM events, renderElement, renderLeaf, and renderText.
Plugin slotsbeforeEditable, aboveEditable, and afterEditable wrap or sit around the editable surface.
EffectsEditorShortcutDispatcher, EditorRefEffect, and PlateControllerEffect run inside PlateContent.
Read-only statedisabled forces read-only; readOnly syncs back into the Plate store.

Node Primitives

Use PlateElement, PlateLeaf, and PlateText inside plugin components. They merge Plite attributes with your className, style, and ref.

components/paragraph-element.tsx
import {
  ParagraphPlugin,
  PlateElement,
  type PlateElementProps,
} from "platejs/react";
 
export function ParagraphElement(
  props: PlateElementProps<typeof ParagraphPlugin>
) {
  return <PlateElement as="p" className="leading-7" {...props} />;
}
components/paragraph-element.tsx
import {
  ParagraphPlugin,
  PlateElement,
  type PlateElementProps,
} from "platejs/react";
 
export function ParagraphElement(
  props: PlateElementProps<typeof ParagraphPlugin>
) {
  return <PlateElement as="p" className="leading-7" {...props} />;
}

Pass a plugin descriptor when the component belongs to one plugin. The props infer that plugin's configured element type.

components/quote-element.tsx
import { QuotePlugin } from "@/components/editor/quote-plugin";
import { PlateElement, type PlateElementProps } from "platejs/react";
 
export function QuoteElement(props: PlateElementProps<typeof QuotePlugin>) {
  return <PlateElement as="blockquote" {...props} />;
}
components/quote-element.tsx
import { QuotePlugin } from "@/components/editor/quote-plugin";
import { PlateElement, type PlateElementProps } from "platejs/react";
 
export function QuoteElement(props: PlateElementProps<typeof QuotePlugin>) {
  return <PlateElement as="blockquote" {...props} />;
}

Low-level renderer infrastructure that has no plugin owner uses the raw render contract instead:

import type { Element, RenderElementProps } from "platejs";
 
export function TypedElement<TElement extends Element>(
  props: RenderElementProps<TElement>
) {
  return <div {...props.attributes}>{props.children}</div>;
}
import type { Element, RenderElementProps } from "platejs";
 
export function TypedElement<TElement extends Element>(
  props: RenderElementProps<TElement>
) {
  return <div {...props.attributes}>{props.children}</div>;
}

When a schema element owns a named content root, render it through the typed slots.contentRoot(slot) function. The same component works in interactive and static rendering; Plate chooses an editable root view or static root children.

components/figure-element.tsx
import { FigurePlugin } from "@/components/editor/figure-plugin";
import type { PlateElementProps } from "platejs/react";
 
export function FigureElement({
  attributes,
  children,
  slots,
}: PlateElementProps<typeof FigurePlugin>) {
  return (
    <figure {...attributes}>
      {children}
      <figcaption>{slots.contentRoot("caption")}</figcaption>
    </figure>
  );
}
components/figure-element.tsx
import { FigurePlugin } from "@/components/editor/figure-plugin";
import type { PlateElementProps } from "platejs/react";
 
export function FigureElement({
  attributes,
  children,
  slots,
}: PlateElementProps<typeof FigurePlugin>) {
  return (
    <figure {...attributes}>
      {children}
      <figcaption>{slots.contentRoot("caption")}</figcaption>
    </figure>
  );
}
PrimitiveBehavior
PlateElementAdds data-plite-node="element", preserves Plite's data-plite-node-key, exposes typed element-owned content-root slots, and adds directional-affinity spacers when needed.
PlateLeafRenders a text leaf and adds hard-affinity spacers when needed.
PlateTextRenders a text node without leaf-decoration matching.

Node Selection

Plite stores node selection in the editor model. Plate React provides two independent DOM primitives for its visual presentation and pointer-drag input. Compose them as siblings after PlateContent under the same Plate provider.

components/editor.tsx
import {
  NodeSelectionDrag,
  NodeSelectionHighlight,
  PlateContent,
  type PlateContentProps,
} from "platejs/react";
 
export function Editor(props: PlateContentProps) {
  return (
    <>
      <PlateContent {...props} />
      <NodeSelectionHighlight className="z-1 bg-brand/[.13]" />
      <NodeSelectionDrag className="z-50 border border-brand/25 bg-brand/15" />
    </>
  );
}
components/editor.tsx
import {
  NodeSelectionDrag,
  NodeSelectionHighlight,
  PlateContent,
  type PlateContentProps,
} from "platejs/react";
 
export function Editor(props: PlateContentProps) {
  return (
    <>
      <PlateContent {...props} />
      <NodeSelectionHighlight className="z-1 bg-brand/[.13]" />
      <NodeSelectionDrag className="z-50 border border-brand/25 bg-brand/15" />
    </>
  );
}

NodeSelectionHighlight portals a highlight into each selected block. NodeSelectionDrag renders the active drag rectangle in document.body and writes intersecting blocks through the editor's selection API. Selection candidates must pass editor.read.schema.isBlockContent(element) and editor.read.nodes.isSelectable(element).

Structural internals opt out with blockContent: false. A block that owns custom highlight geometry sets data-node-selection-highlight="self" and can read its exact state with useElementSelected({ mode: "node" }).

PrimitiveDOM contract
NodeSelectionHighlightAccepts div attributes except children; renders data-slot="node-selection-highlight" with required inset positioning.
NodeSelectionDragAccepts div attributes except children; renders data-slot="node-selection-drag" with required fixed positioning.

Use the Selection API for model reads and writes. See the Node Selection demo for the copied Editor composition.

API Reference

Plate

Root provider for one editor instance.

Props

    Editor instance. When null, Plate renders nothing.

    React children that can read the Plate store.

    Store-level decorate function used by PlateContent.

    Store-level read-only state. Defaults to editor.dom.readOnly.

    Registers the editor as a primary editor for PlateController.

    Fallback element renderer stored on the Plate store.

    Fallback leaf renderer stored on the Plate store.

    Observes every published editor commit for the lifetime of the Plate provider.

    Observes commits that change the serializable document. value contains primary children, named roots, and persisted meta.

    Observes commits that change the primary-root selection.

    Observes canonical node changes for the lifetime of the Plate provider.

    Observes canonical text changes for the lifetime of the Plate provider.

    Suppresses the multiple-instance warning from usePlateInstancesWarn.

PlateContent

Editable surface for a Plate editor.

Props

    Editor scope used by useEditor({id}) and usePlateStore(id).

    Focuses the editor at the end when readOnly changes from true to false.

    Forces read-only state and sets aria-disabled.

    Overrides the store read-only value and syncs it back to the store.

    Editable-level decorate function. Store-level decorate wins when present.

    Wraps or replaces the generated Editable element.

    Fallback element renderer after plugin renderers.

    Fallback leaf renderer after plugin leaf renderers.

    Fallback text renderer after non-decoration text renderers.

    Placeholder renderer passed to Plite Editable.

    Placeholder text passed to Plite Editable.

    Plite selection scrolling hook.

    DOM before-input handler passed through the plugin handler pipeline.

    Keyboard handler passed through the plugin handler pipeline.

    Element type passed to Plite Editable.

    Passed to Plite Editable.

    ARIA role passed to Plite Editable.

    Style object passed to Plite Editable.

PlateContent also accepts the DOM handler props listed in DOMHandlers, including clipboard, composition, focus, keyboard, pointer, mouse, drag, touch, media, and form handlers.

PlateView

Read-only static renderer with Plate copy support.

Props

    Static editor instance.

    Overrides the default Plate fragment copy handler.

    Merged with the plite-editor class by PlateStatic.

    Style object passed to the static root div.

PlateContainer

Container div with plugin container slots.

Props

    Content rendered inside the container.

    HTML props passed to the container div and container slot components.

Render Primitives

APIDefault ElementNotes
PlateElementdivAccepts as, attributes, className, style, ref, element, path, editor, plugin, and insetProp.
PlateLeafspanAccepts as, attributes, className, style, ref, leaf, text, editor, plugin, and inset.
PlateTextspanAccepts as, attributes, className, style, ref, text, editor, and plugin.