Save Plate JSON when another Plate editor must recover the editable document. Use a format parser or serializer when content crosses an application boundary.
| Task | Surface |
|---|---|
| Persist the complete editor document | editor.read.value() |
| Persist exact proposals and decisions | projectAuthoredReview and parseAuthoredDocument |
| Convert semantic HTML | platejs/html; Node parsing uses |
platejs/html/server| Convert Markdown | platejs/markdown |
| Import or export Word | platejs/docx/import and platejs/docx/export |
| Render component-styled HTML | platejs/static |
| Exchange browser clipboard MIME payloads | DataTransferFormat through platejs/dom |
There is no universal document converter. Each format owns its syntax, diagnostics, loss policy, limits, and retained source.
editor.read.value() includes the primary children, named roots, and persistent
metadata.
const document = editor.read.value();
const schema = editor.read.schema.identity();
await saveDocument({ document, schema });const document = editor.read.value();
const schema = editor.read.schema.identity();
await saveDocument({ document, schema });Saving only children drops roots and metadata. Persist an application schema
identity when stored documents require versioned migration. Validate migrated
data before publishing it to an editor.
Exact authored review state is canonical JSON-compatible model data:
import { parseAuthoredDocument, projectAuthoredReview } from 'platejs/authored';
const snapshot = projectAuthoredReview(editor.read.value());
const json = JSON.stringify(snapshot.review);
const document = parseAuthoredDocument(json);import { parseAuthoredDocument, projectAuthoredReview } from 'platejs/authored';
const snapshot = projectAuthoredReview(editor.read.value());
const json = JSON.stringify(snapshot.review);
const document = parseAuthoredDocument(json);HTML, Markdown, and DOCX do not hide an authored document in their output.
A document from an editor with authored changes installed carries authored
metadata even before any proposal. Every HTML, Markdown, plain-text and static
HTML export of it throws a TypeError unless projection is 'accepted' or
'proposed'. A document without authored metadata needs no projection.
import { serializePlainText } from 'platejs';
const result = serializePlainText(editor, { projection: 'accepted' });import { serializePlainText } from 'platejs';
const result = serializePlainText(editor, { projection: 'accepted' });Feature plugins contribute structural plainText mappings through
formats/defineFormats. Plain text is one-way output; it does not become a
universal parser or persistence format.
Use direct functions for detached work:
import { parseHtml, serializeHtml } from 'platejs/html';
const parsed = parseHtml(source, { plugins: EditorKit });
const output = serializeHtml(document, {
plugins: EditorKit,
projection: 'accepted',
});import { parseHtml, serializeHtml } from 'platejs/html';
const parsed = parseHtml(source, { plugins: EditorKit });
const output = serializeHtml(document, {
plugins: EditorKit,
projection: 'accepted',
});In Node.js, import parseHtml from platejs/html/server. Install linkedom
for that server-only DOM adapter.
Install HtmlPlugin when a configured editor should expose
editor.api.html.parse, parseSlice, and serialize. See HTML.
import { parseMarkdown, serializeMarkdown } from 'platejs/markdown';
const parsed = parseMarkdown(source, { plugins: EditorKit });
const output = serializeMarkdown(document, {
plugins: EditorKit,
projection: 'proposed',
});import { parseMarkdown, serializeMarkdown } from 'platejs/markdown';
const parsed = parseMarkdown(source, { plugins: EditorKit });
const output = serializeMarkdown(document, {
plugins: EditorKit,
projection: 'proposed',
});Install MarkdownPlugin for editor.api.markdown.parse, parseSlice,
parseInline, and serialize. See Markdown.
DOCX import is detached. Supply the complete plugin target before the operation starts, then publish a successful document explicitly.
import { importDocx } from 'platejs/docx/import';
const result = await importDocx(file, { plugins: EditorKit });
if (result.ok) {
editor.update((tx) => tx.value.replace(result.document));
}import { importDocx } from 'platejs/docx/import';
const result = await importDocx(file, { plugins: EditorKit });
if (result.ok) {
editor.update((tx) => tx.value.replace(result.document));
}DOCX export captures a configured editor because static rendering, comments, retained source, and Word revisions are part of its package workflow.
import { exportDocx } from 'platejs/docx/export';
import { BaseEditorKit } from '@/components/editor/plugins-static';
const result = await exportDocx(editor, {
presentation: BaseEditorKit,
projection: 'review',
});import { exportDocx } from 'platejs/docx/export';
import { BaseEditorKit } from '@/components/editor/plugins-static';
const result = await exportDocx(editor, {
presentation: BaseEditorKit,
projection: 'review',
});A live editor's components are editing UI, so pass the app's static kit as
presentation to draw the file.
A Word file contains the visible Word document, its comments, and its tracked revisions. Save Plate JSON beside it when another Plate editor must recover named roots, metadata, or exact authored change records.
See DOCX for cancellation, package limits, comments, and retained source.
HTML, Markdown, and DOCX use format-specific diagnosed results. Success carries warnings and the requested document, slice, string, or Blob. Failure carries a nonempty error-first diagnostic tuple and no publishable carrier.
const result = editor.api.markdown.serialize({ projection: 'accepted' });
showDiagnostics(result.diagnostics);
if (!result.ok) return;
downloadMarkdown(result.data);const result = editor.api.markdown.serialize({ projection: 'accepted' });
showDiagnostics(result.diagnostics);
if (!result.ok) return;
downloadMarkdown(result.data);Expected source failure and representational loss return diagnostics.
Configuration errors, mapping bugs, and invalid serializer model data throw.
lossPolicy defaults to 'reject'; opt into 'allow' only when the caller
accepts the exact reported loss.
Feature plugins declare semantic mappings through formats and
defineFormats using the html, markdown, and plainText keys. The narrow
authoring callback cannot read a live editor or store.
Whole browser MIME payloads use DataTransferFormat, not feature mappings.
Clipboard insertion remains destination-aware and can preserve native open
edges and detached roots. See Plugin Methods and
Clipboard.
A complete parse returns EditorDocumentValue. Direct syntax slice or inline
parsing returns a closed, rootless ContentSlice. The insertion owner fits that
slice once the destination is known.
const result = editor.api.markdown.parseSlice(source);
if (result.ok) editor.update.slice.replace(result.slice);const result = editor.api.markdown.parseSlice(source);
if (result.ok) editor.update.slice.replace(result.slice);Do not turn a complete document into children before replacement; that drops
named roots and metadata. Do not invent a destination during detached parsing.