From zbeyens. The source code is available on GitHub.

Plate
PlatePliteEditorsTemplates
GitHub16kGitHub
DiscordDiscord
UNPUBLISHED
  • Overview
  • Why This Fork
  • Examples
Walkthroughs
  • Installing Plite
  • Adding Event Handlers
  • Defining Custom Elements
  • Applying Custom Formatting
  • Executing Commands
  • Saving to a Database
  • Canonical Change Substrate
  • Improving Performance
Concepts
  • Interfaces
  • Nodes
  • Locations
  • Transforms
  • Document Changes
  • Commands
  • Editor
  • Extensions
  • Rendering
  • Serializing
  • Normalizing
  • Using TypeScript
  • Roots
  • Document State
  • Editing Behavior
  • Selection And DOM
  • Clipboard And Paste
  • Projection And Overlays
  • Schema
API
  • Anchor API
  • Location API
  • Path API
  • PointEntry API
  • Point API
  • Range API
  • Selection API
  • Location Types APIs
  • Span API
  • Editor
  • Element API
  • NodeEntry API
  • Node API
  • Node Types APIs
  • Text API
  • Debug Value Scrubbing
  • Transforms API
Libraries
  • Plite DOM
  • History Editor API
  • History Extension Setup
  • History
  • Plite History
  • Plite Hyperscript
  • Plite Layout
  • Annotations
  • DOM Coverage Boundaries
  • Editable Component
  • Plite React Event Handling
  • Virtualized Rendering
  • Plite React Hooks
  • React Editor Setup
  • React Editor
  • Plite React
  • Plite Component
  • Plite Yjs
  • Plite
General
  • Migration
  • Contributing
  • Docs Proof Map
  • FAQ
  • Resources

Installing Plite

PreviousNext

Install the React editor packages and render the smallest useful Plite editor.

Plite is split into small packages. For a React editor, install the core editor, the DOM helpers, the React renderer, and React itself.

Installation

Install the React editor path first.

pnpm add @platejs/plite @platejs/plite-dom @platejs/plite-react react react-dom
pnpm add @platejs/plite @platejs/plite-dom @platejs/plite-react react react-dom
PackageOwns
@platejs/pliteeditor runtime, document model, transactions, helper APIs
MigrationAdding Event Handlers

On This Page

InstallationUsageListening For ChangesNext steps
Build your editor
Production-ready AI template and reusable components.
Get all-access
@platejs/plite-dom
DOM conversion, clipboard helpers, browser environment helpers
@platejs/plite-react<Plite>, <Editable>, React hooks, editor setup
react, react-domReact peer packages

Usage

Import the React editor pieces from @platejs/plite-react.

import {
  Editable,
  Plite,
  type PliteValueChangeContext,
  usePliteEditor,
} from "@platejs/plite-react";
import {
  Editable,
  Plite,
  type PliteValueChangeContext,
  usePliteEditor,
} from "@platejs/plite-react";

Before we render anything, let's define the document shape for this editor.

type CustomText = { text: string };
type ParagraphElement = { type: "paragraph"; children: CustomText[] };
type CustomValue = ParagraphElement[];
 
const initialValue: CustomValue = [
  {
    type: "paragraph",
    children: [{ text: "A line of text in a paragraph." }],
  },
];
type CustomText = { text: string };
type ParagraphElement = { type: "paragraph"; children: CustomText[] };
type CustomValue = ParagraphElement[];
 
const initialValue: CustomValue = [
  {
    type: "paragraph",
    children: [{ text: "A line of text in a paragraph." }],
  },
];

CustomValue is the TypeScript shape of this editor's primary document. Passing it to usePliteEditor keeps element and text types attached to the editor API.

Call usePliteEditor inside the component so React keeps the same editor object for the component lifetime.

Render the editor with <Plite> and <Editable>.

const App = () => {
  const editor = usePliteEditor<CustomValue>({ initialValue });
 
  return (
    <Plite editor={editor}>
      <Editable />
    </Plite>
  );
};
const App = () => {
  const editor = usePliteEditor<CustomValue>({ initialValue });
 
  return (
    <Plite editor={editor}>
      <Editable />
    </Plite>
  );
};

The editor is seeded by usePliteEditor({ initialValue }). <Plite> provides that existing editor to everything underneath it, and <Editable> renders the editable document surface.

This is the smallest useful Plite editor. If you render App, you should see a paragraph with the text A line of text in a paragraph. When you type, Plite updates the document through the editor runtime.

Listening For Changes

Most applications save the document value somewhere. Use onValueChange for a single-root document.

const App = () => {
  const editor = usePliteEditor<CustomValue>({ initialValue });
 
  const handleValueChange = ({
    value,
  }: PliteValueChangeContext<CustomValue>) => {
    localStorage.setItem("content", JSON.stringify(value));
  };
 
  return (
    <Plite editor={editor} onValueChange={handleValueChange}>
      <Editable />
    </Plite>
  );
};
const App = () => {
  const editor = usePliteEditor<CustomValue>({ initialValue });
 
  const handleValueChange = ({
    value,
  }: PliteValueChangeContext<CustomValue>) => {
    localStorage.setItem("content", JSON.stringify(value));
  };
 
  return (
    <Plite editor={editor} onValueChange={handleValueChange}>
      <Editable />
    </Plite>
  );
};

Use initialValue as the one-shot initial document passed to usePliteEditor. If your app needs to replace the whole document after the editor exists, use an explicit editor update instead of treating <Plite> like a controlled <textarea>.

Next steps

The editor is rendering plain text. Next, add event handlers so the editor can respond to keyboard shortcuts.