Plate
PlateEditorsTemplates
GitHub16kGitHub
DiscordDiscord
    • Overview
    • Why This Fork
    • Examples
    • Installing Plite
    • Adding Event Handlers
    • Defining Custom Elements
    • Applying Custom Formatting
    • Executing Commands
    • Saving to a Database
    • Canonical Change Substrate
    • Improving Performance
    • Interfaces
    • Nodes
    • Locations
    • Transforms
    • Document Changes
    • Commands
    • Editor
    • Plugins
    • Rendering
    • Serializing
    • Normalizing
    • Using TypeScript
    • Roots
    • Document State
    • Editing Behavior
    • Selection And DOM
    • Clipboard And Paste
    • Decorations, annotations, and widgets
    • Schema
    • 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
    • Plite DOM
    • History Editor API
    • History Plugin Setup
    • History
    • Plite History
    • Plite Hyperscript
    • Plite PaginationExperimental
    • Annotations
    • DOM Coverage Boundaries
    • Editable Component
    • External Text Views
    • Plite React Event Handling
    • Virtualized Rendering
    • Plite React Hooks
    • React Editor Setup
    • React Editor
    • Plite React
    • Plite Component
    • Plite Yjs
    • Plite
    • Migration
    • Contributing
    • FAQ
    • Resources

History Plugin Setup

PreviousNext

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

Install history with the history() plugin.

Core editor setup

import { createEditor } from "plitejs";
import { history } from "plitejs/history";
 
const editor = createEditor({
  plugins: [history({ maxDepth: 100, newBatchDelay: 500 })],
  initialValue: [{ type: "paragraph", children: [{ text: "" }] }],
});
import { createEditor } from "plitejs";
import { history } from "plitejs/history"




newBatchDelay defaults to 500 milliseconds. It starts a new undo batch when an otherwise-compatible automatic native edit arrives after that idle window. maxDepth defaults to 100 batches per branch. Updated values apply to the next accepted update or replay; reading history does not trim a branch. Explicit tx.history.merge() and tx.history.newBatch() decisions remain authoritative, and no timing metadata is serialized with history.

Install history() explicitly when a React-owned editor needs undo and redo. Use history({ enabled: false }) to disable history supplied by a preset.

React editor setup

import { history } from "plitejs/history";
import { useEditor } from "plitejs/react";
 
const editor = useEditor({
  plugins: [history({ enabled: false })],
  initialValue,
});
import { history } from "plitejs/history";
import { useEditor } from "plitejs/react";
 
const editor = useEditor({


Read history through editor.read.history (or state.history inside a grouped read), replay through editor.api.history, and use tx.history or an editor.update({ history }) policy to control the update being built.

Runtime API

These examples assume an editor with history enabled.

const canUndo = editor.read.history.hasUndo();
const result = editor.api.history.undo();
 
editor.update({ history: "skip" }).text.insert("draft");
 
editor.update((tx) => {
  tx.history.newBatch();
  tx.text.insert("separate undo step");
});
const canUndo







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({
plugins: [history({ maxDepth: 100, newBatchDelay: 500 })],
initialValue: [{ type: "paragraph", children: [{ text: "" }] }],
});
plugins: [
history
({ enabled:
false
})],
initialValue,
});
=
editor.read.history.
hasUndo
();
const result = editor.api.history.undo();
editor.update({ history: "skip" }).text.insert("draft");
editor.update((tx) => {
tx.history.newBatch();
tx.text.insert("separate undo step");
});