Undo and Redo in Angular Block Editor

The undo/redo feature in Block Editor enables users to revert or reapply changes made to the content, offering a safety net for edits and enhancing the overall editing experience.

Keyboard shortcuts

The Block Editor responds to the following standard keyboard shortcuts for undo and redo:

Action Windows Mac Description
Undo Ctrl + Z ⌘ + Z Reverts the last action.
Redo Ctrl + Y ⌘ + Y Reapplies the last undone action.

Configuring the undo/redo stack

The Block Editor stores a history of actions, allowing users to perform undo and redo operations. By default, it retains up to 30 actions. You can customize this limit through the undoRedoStack property on the editor, which sets the maximum number of steps that can be undone or redone.

The example below sets the undo/redo history limit to 20 actions. The editor then keeps the last 20 changes in memory and discards anything older.

import { Component } from '@angular/core';
import { BlockEditorModule } from "@syncfusion/ej2-angular-blockeditor";
import { BlockModel, ContentType} from "@syncfusion/ej2-blockeditor";

@Component({
    imports: [BlockEditorModule],
    standalone: true,
    selector: 'app-root',
    templateUrl: './app.component.html'
})


export class AppComponent {
    public blocksData: BlockModel[] = [
        {
            blockType: 'Heading',
            properties: { level: 1},
            content: [
                {
                    contentType: ContentType.Text,
                    content: 'Undo/Redo Demo'
                }
            ]
        },
        {
            blockType: 'Paragraph',
            content: [
                {
                    contentType: ContentType.Text,
                    content: 'Try adding new blocks or modifying content below:'
                }
            ]
        },
        {
            blockType: 'Paragraph',
            content: [
                {
                    contentType: ContentType.Text,
                    content: '1. Undo stack set to maximum 40 actions\n2. Press Ctrl+Z to undo\n3. Press Ctrl+Y to redo\n4. Actions include text edits, block moves, additions, deletions'
                }
            ]
        }
    ];
    public undoRedoStack = 20;
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
<div id="container">
    <ejs-blockeditor id="blockeditor" [blocks]="blocksData" [undoRedoStack]="undoRedoStack" />
</div>

Memory note: Each entry in the undo/redo stack is a snapshot of the affected block, so a very large undoRedoStack value (for example, several hundred) can noticeably increase memory consumption in long-lived editor sessions. Tune this value to match how many changes a user is realistically likely to undo.

Programmatic undo/redo

The Block Editor does not expose public undo() / redo() methods. The undo and redo operations are triggered through the keyboard shortcuts (or any UI that simulates them). If you need to react to undo and redo state changes programmatically, observe the editor’s blockChanged event and track the change direction in your own state, or wire up custom buttons that dispatch the same keyboard events to the editor element:

<button (click)="triggerUndo()">Undo</button>
<button (click)="triggerRedo()">Redo</button>

<ejs-blockeditor #editor [blocks]="blocksData" />
import { ViewChild, ElementRef } from '@angular/core';
// ...
@ViewChild('editor') public editor!: ElementRef;

public triggerUndo(): void {
    // The editor listens for Ctrl+Z / Cmd+Z on its host element.
    this.editor.nativeElement.dispatchEvent(
        new KeyboardEvent('keydown', { key: 'z', ctrlKey: true, bubbles: true })
    );
}

public triggerRedo(): void {
    this.editor.nativeElement.dispatchEvent(
        new KeyboardEvent('keydown', { key: 'y', ctrlKey: true, bubbles: true })
    );
}

For most apps, prefer the built-in inline toolbar and the context menu actions, which already include undo and redo entries by default.