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

History Extension Setup

PreviousNext

Install or disable the history extension in core and React-owned editors.

Install history with the history() extension.

Core Editor Setup

import { createEditor } from "@platejs/plite";
import { history } from "@platejs/plite-history";
 
const editor = createEditor({
  extensions: [history({ newBatchDelay: 500 })],
  initialValue: [{ type: "paragraph", children: [{ text: "" }] }],
});
import { createEditor } from "@platejs/plite";
import { history } from "@platejs/plite-history";
 



newBatchDelay defaults to 500 milliseconds. It starts a new undo batch when an otherwise-compatible automatic native edit arrives after that idle window. Explicit tx.history.merge() and tx.history.newBatch() decisions remain authoritative, and no timing metadata is serialized with history.

usePliteEditor installs history by default. Disable it explicitly when a React-owned editor should not expose history state or transaction helpers.

React Editor Setup

import { history } from "@platejs/plite-history";
import { usePliteEditor } from "@platejs/plite-react";
 
const editor = usePliteEditor({
  extensions: [history({ enabled: false })],
  initialValue,
});
import { history } from "@platejs/plite-history";
import { usePliteEditor } from "@platejs/plite-react";
 
const editor = usePliteEditor({


Read history through state.history, write through tx.history, and use an editor.update({ history }) policy for one controlled update.

Runtime API

const undoCount = editor.read((state) => state.history.undos().length);
 
editor.update((tx) => {
  tx.history.undo();
});
 
editor.update({ history: "skip" }).text.insert("draft");
 
editor.update((tx) => {
  tx.history.newBatch();
  tx.text.insert("separate undo step");
});

See History Editor API for the full API surface.

History Editor APIHistory

On This Page

Core Editor SetupReact Editor SetupRuntime API
Build your editor
Production-ready AI template and reusable components.
Get all-access
const
editor
=
createEditor
({
extensions: [history({ newBatchDelay: 500 })],
initialValue: [{ type: "paragraph", children: [{ text: "" }] }],
});
extensions: [history({ enabled: false })],
initialValue,
});
const undoCount = editor.read((state) => state.history.undos().length);
 
editor.update((tx) => {
  tx.history.undo();
});
 
editor.update({ history: "skip" }).text.insert("draft");
 
editor.update((tx) => {
  tx.history.newBatch();
  tx.text.insert("separate undo step");
});