In-Memory Versioning
This example shows how to use the VersioningExtension without any collaboration layer (no Yjs required). Snapshots are stored in memory using ProseMirror JSON.
Try it out: Edit the document, then use the Version History sidebar to save snapshots, preview older versions, rename them, and restore them. You can hide the sidebar with the close button and reopen it with the "History" button.
import "@blocknote/core/fonts/inter.css";import { VersioningExtension, createInMemoryVersioningAdapter,} from "@blocknote/core/extensions";import { DiffVersioningExtension } from "@blocknote/core/y";import { BlockNoteViewEditor, useCreateBlockNote, useExtensionState, VersioningSidebar,} from "@blocknote/react";import { BlockNoteView } from "@blocknote/mantine";import "@blocknote/mantine/style.css";import { useState } from "react";import "./style.css";export default function App() { // `createInMemoryVersioningAdapter` is passed as a factory function. The // VersioningExtension will call it with the editor instance once it's ready. const editor = useCreateBlockNote({ initialContent: [ { type: "heading", content: "In-Memory Versioning Example", props: { level: 2 }, }, { type: "paragraph", content: "This example demonstrates versioning without any collaboration layer. " + "Snapshots are stored in memory using ProseMirror JSON — no Yjs required.", }, { type: "paragraph", content: "Try editing this document, then use the Version History sidebar to " + "save snapshots. You can preview and restore older versions.", }, ], extensions: [ VersioningExtension(createInMemoryVersioningAdapter), // Opt into rendering version diffs: when comparing two versions the // sidebar shows insertions/deletions as attributed marks. Without this // extension the in-memory versioning falls back to a plain document swap. DiffVersioningExtension(), ], }); const { previewedSnapshotId } = useExtensionState(VersioningExtension, { editor, }); const [showSidebar, setShowSidebar] = useState(true); return ( <div className="wrapper"> <BlockNoteView editor={editor} editable={previewedSnapshotId === undefined} renderEditor={false} > <div className="layout"> <div className="editor-panel"> <BlockNoteViewEditor /> {!showSidebar && ( <button className="show-history-button" onClick={() => setShowSidebar(true)} > History </button> )} </div> {showSidebar && ( <div className={"sidebar-section"}> <VersioningSidebar filter={"all"} onClose={() => setShowSidebar(false)} /> </div> )} </div> </BlockNoteView> </div> );}/* App layout only. The versioning sidebar's own styling (header, snapshot rows, selected/comparing states, the "..." menu) ships with the UI library (@blocknote/mantine etc.), so it isn't repeated here. */.wrapper { height: calc(100vh - 20px);}.wrapper > .bn-container { margin: 0; max-width: none; padding: 0;}.layout { display: flex; gap: 0; height: calc(100vh - 20px);}.editor-panel { flex: 1; height: calc(100vh - 20px); min-width: 0; overflow: auto; position: relative;}.editor-panel .bn-container { height: calc(100vh - 20px); margin: 0; max-width: none; padding: 0;}.editor-panel .bn-editor { height: calc(100vh - 20px); overflow: auto;}/* The history panel sits flush against the editor with a subtle divider. */.sidebar-section { background-color: var(--bn-colors-editor-background); border-left: 1px solid var(--bn-colors-border); box-shadow: -6px 0 16px rgba(0, 0, 0, 0.05); display: flex; flex-direction: column; height: calc(100vh - 20px); overflow: auto; width: 350px;}.dark .sidebar-section { border-left-color: #2c2c2c; box-shadow: -6px 0 16px rgba(0, 0, 0, 0.3);}.show-history-button { background-color: var(--bn-colors-menu-background); border: var(--bn-border); border-radius: var(--bn-border-radius-medium); box-shadow: var(--bn-shadow-medium); color: var(--bn-colors-menu-text); cursor: pointer; font-size: 13px; font-weight: 600; padding: 6px 12px; position: absolute; right: 16px; top: 16px;}