Plate
PlateEditorsTemplates
GitHub16kGitHub
DiscordDiscord
  • Feature Kits
  • Plugin
    • Plugin Methods
    • Plugin Shortcuts
    • Plugin Context
    • Plugin Components
    • Plugin Rules
    • Editing Behavior
    • Plugin Input Rules
  • Editor
    • Editor Methods
    • Controlled Value
  • Authored Changes
  • Performance
  • Static Rendering
  • HTML
  • Markdown
  • Form
  • TypeScript
  • Debugging
  • Unit Testing
  • Browser
  • Troubleshooting
  • Locations
  • Transactions
  • Serializing
  • Roots
  • Document Meta
  • Clipboard and Paste
  • Decorations, annotations, and widgets
  • Schema
  • History
  • Pagination
  • Annotations
  • DOM Coverage
  • External Text Views
  • Virtualized Rendering

Virtualized Rendering

PreviousNext

Explicitly omit offscreen top-level blocks from a large editor's DOM.

VirtualizedEditorContent mounts a measured window of top-level blocks. Use it when a complete document DOM exceeds the product's tested interaction or memory budget. Ordinary EditorContent always mounts the complete document.

Usage

Install the virtualizer with React:

pnpm add platejs @tanstack/react-virtual react react-dom
pnpm add platejs @tanstack/react-virtual react react-dom

Render VirtualizedEditorContent from its dedicated entrypoint. Give it a bounded scroll surface, either on the editable itself or on an ancestor.

import { EditorRoot, useCreateEditor } 












External Text ViewsOverview

On This Page

UsageInitial renderingDOM omissionNative behavior limits
Build your editor
Production-ready AI template and reusable components.
Get all-access
from
"platejs/react"
;
import { VirtualizedEditorContent } from "platejs/react/virtualized";
const editor = useCreateEditor({ initialValue });
return (
<EditorRoot editor={editor}>
<VirtualizedEditorContent
estimatedBlockSize={32}
overscan={4}
style={{ height: 480, overflowY: "auto" }}
/>
</EditorRoot>
);
import { EditorRoot, useCreateEditor } from "platejs/react";
import { VirtualizedEditorContent } from "platejs/react/virtualized";
 
const editor = useCreateEditor({ initialValue });
 
return (
  <EditorRoot editor={editor}>
    <VirtualizedEditorContent
      estimatedBlockSize={32}
      overscan={4}
      style={{ height: 480, overflowY: "auto" }}
    />
  </EditorRoot>
);

estimatedBlockSize defaults to 32 CSS pixels and must be a positive finite number. overscan defaults to 2 and must be a nonnegative integer. Plate owns the item keys, range extraction, measurement, and scroll targeting.

Initial rendering

Before Plate can measure a scroll owner, the virtualized surface renders the first eight top-level blocks plus selected or requested targets. The same rule applies to server rendering, detached roots, hidden roots, and zero-size roots, so the first client render agrees with the server markup.

Measured viewport changes and option changes retain mounted rows by node key. Switching between EditorContent and VirtualizedEditorContent creates a different mounted view. Remount deliberately and restore any app-owned view state when a product changes that choice.

DOM omission

Unmounted content remains in the Plate value, history, and collaboration state, but it has no native DOM. Model selection and clipboard serialization can cross an omitted range. Selected endpoints stay mounted, and Plate mounts a requested target before scrolling or editing it.

Native behavior limits

AreaBehavior
Browser findNative find sees mounted blocks only.
Screen readersAssistive technology traverses mounted blocks only.
Print and exportDOM-based output includes mounted blocks only.
CopyPlate serializes selected model content to plain text, HTML, and its fragment format.

Use EditorContent when the product requires complete native find, accessibility traversal, print output, or third-party DOM access. Virtualized mobile selection and IME behavior need browser and device proof for the product's supported matrix.

See DOM Coverage Boundaries for selection, copy, materialization, and native find limits at unmounted ranges.