HTML serializer plugin for Plate rich text editor framework enabling bidirectional conversion between Slate nodes and HTML format
—
Low-level utilities for processing HTML documents, fragments, and converting between HTML strings and Slate document structures. These functions provide the foundation for both serialization and deserialization operations.
Functions for handling complete HTML documents and converting them to Slate-compatible formats.
/**
* Deserialize HTML element to a valid document fragment
* @param editor - Plate editor instance
* @param options - Document fragment processing options
* @returns Array of Slate descendants representing the document
*/
function deserializeHTMLToDocumentFragment<T = {}>(
editor: PlateEditor<T>,
options: DocumentFragmentOptions<T>
): TDescendant[];
interface DocumentFragmentOptions<T> {
/** Array of Plate plugins for deserialization rules */
plugins: PlatePlugin<T>[];
/** HTML element or string to deserialize */
element: HTMLElement | string;
/** Whether to strip whitespace from the HTML (default: true) */
stripWhitespace?: boolean;
}Usage Examples:
import { deserializeHTMLToDocumentFragment } from "@udecode/plate-html-serializer";
// Process HTML string to document fragment
const htmlString = `
<div>
<h1>Title</h1>
<p>First paragraph with <strong>bold</strong> text.</p>
<ul>
<li>List item 1</li>
<li>List item 2</li>
</ul>
</div>
`;
const documentFragment = deserializeHTMLToDocumentFragment(editor, {
plugins: myPlugins,
element: htmlString,
stripWhitespace: true
});
// Process HTML element to document fragment
const htmlElement = document.createElement('article');
htmlElement.innerHTML = '<h2>Article Title</h2><p>Article content...</p>';
const articleFragment = deserializeHTMLToDocumentFragment(editor, {
plugins: myPlugins,
element: htmlElement,
stripWhitespace: false
});
// Complex document with mixed content
const complexHtml = `
<div>
<blockquote>
<p>This is a quote with <em>emphasis</em>.</p>
</blockquote>
<pre><code>console.log('code block');</code></pre>
<p>Regular paragraph after code.</p>
</div>
`;
const complexFragment = deserializeHTMLToDocumentFragment(editor, {
plugins: [
// Include plugins for blockquote, code, emphasis, etc.
blockquotePlugin,
codePlugin,
emphasisPlugin
],
element: complexHtml
});Utility for converting HTML strings into DOM elements for further processing.
/**
* Convert HTML string into HTML element
* @param rawHtml - HTML string to convert
* @param stripWhitespace - Whether to strip whitespace characters (default: true)
* @returns HTMLElement with the parsed content as body element
*/
function htmlStringToDOMNode(
rawHtml: string,
stripWhitespace?: boolean
): HTMLElement;Usage Examples:
import { htmlStringToDOMNode } from "@udecode/plate-html-serializer";
// Basic HTML string conversion
const htmlString = '<p>Hello <strong>world</strong>!</p>';
const domNode = htmlStringToDOMNode(htmlString);
// Access the parsed content
console.log(domNode.tagName); // "BODY"
console.log(domNode.innerHTML); // "<p>Hello <strong>world</strong>!</p>"
// Preserve whitespace formatting
const formattedHtml = `
<div>
<p>Line 1</p>
<p>Line 2</p>
</div>
`;
const preserveWhitespace = htmlStringToDOMNode(formattedHtml, false);
const stripWhitespace = htmlStringToDOMNode(formattedHtml, true);
// Use in deserialization pipeline
const htmlContent = '<div><h1>Title</h1><p>Content</p></div>';
const bodyElement = htmlStringToDOMNode(htmlContent);
const slateNodes = deserializeHTMLElement(editor, {
plugins: myPlugins,
element: bodyElement
});The document processing system follows this workflow:
htmlStringToDOMNodedeserializeHTMLElementnormalizeDescendantsToDocumentFragmentimport {
deserializeHTMLToDocumentFragment,
htmlStringToDOMNode
} from "@udecode/plate-html-serializer";
// Handle paste events
const handlePaste = (event: ClipboardEvent) => {
const html = event.clipboardData?.getData('text/html');
if (html) {
// Convert HTML to Slate nodes
const slateFragment = deserializeHTMLToDocumentFragment(editor, {
plugins: editorPlugins,
element: html,
stripWhitespace: true
});
// Insert into editor
editor.insertFragment(slateFragment);
event.preventDefault();
}
};// Process HTML from API response
const processServerHtml = async (htmlContent: string) => {
// Clean and convert to DOM
const domNode = htmlStringToDOMNode(htmlContent, true);
// Apply any preprocessing to the DOM if needed
preprocessDomNode(domNode);
// Convert to Slate format
const slateContent = deserializeHTMLToDocumentFragment(editor, {
plugins: serverContentPlugins,
element: domNode
});
return slateContent;
};// Process complete HTML documents
const processFullDocument = (htmlDocument: string) => {
// Extract body content if it's a full HTML document
const doc = new DOMParser().parseFromString(htmlDocument, 'text/html');
const bodyContent = doc.body;
// Process with document fragment handler
const slateDocument = deserializeHTMLToDocumentFragment(editor, {
plugins: documentPlugins,
element: bodyContent,
stripWhitespace: true
});
return slateDocument;
};Document processing functions handle various edge cases:
// Robust document processing with error handling
const safeProcessDocument = (html: string) => {
try {
const fragment = deserializeHTMLToDocumentFragment(editor, {
plugins: myPlugins,
element: html || '<p></p>', // Fallback for empty content
stripWhitespace: true
});
// Ensure we have at least one node
return fragment.length > 0 ? fragment : [{ type: 'p', children: [{ text: '' }] }];
} catch (error) {
console.error('Document processing failed:', error);
return [{ type: 'p', children: [{ text: '' }] }]; // Safe fallback
}
};Install with Tessl CLI
npx tessl i tessl/npm-udecode--plate-html-serializer