The editor never produces HTML; it produces a document. Rendering it for a
reader is the reader half of every feature, exported on its own from
@voila.dev/ui/content-editor/reader, an entry that imports neither Plate
nor Slate. A static site build that only renders stored content pays for the
renderer alone.
As HTML
<h2>Writing inside your own app</h2><p>Rich text with <strong>bold</strong>, <em>italic</em> and a <a href="https://ui.voila.dev" rel="noopener noreferrer">link</a>. Type / for a block, or select text for the floating toolbar.</p><aside class="callout"><span aria-hidden="true">💡</span><div>Every block on this page is one feature definition.</div></aside><ul><li>Lists, with Tab to nest</li><li>Tables, images, embeds</li></ul><blockquote>And a quote, for when someone else said it better.</blockquote>
import { contentToHtml, createContentReaders } from "@voila.dev/ui/content-editor/reader";
const READERS = createContentReaders();
const html = contentToHtml(post.body, {
features: READERS,
imageDimensions, // sizes by url, for width and height on <img>
classNameFor: (type) => …, // a class per node type, when your stylesheet names them
});contentToInlineHtml unwraps top-level paragraphs and joins them with
<br>, for a value rendered inside a block the host already has.
collectContentUrls lists every image url, for a build that measures them
first.
As React
Writing inside your own app
Rich text with bold, italic and a link. Type / for a block, or select text for the floating toolbar.
- Lists, with Tab to nest
- Tables, images, embeds
And a quote, for when someone else said it better.
<ContentRenderer value={post.body} features={READERS} render={<article className="prose" />} />Pass createContentReaders the same options as createContentFeatures
(headings, embeds) so the reader renders exactly what the editor edits;
the registry test holds the two sets to the same node types.
API
| Prop | Type | Default | |
|---|---|---|---|
features | ContentReaderRegistry | readonly ContentFeatureReader[] | required | |
value | ContentValue | null | required | |
options | ContentHtmlOptions | {} | |
render | ComponentRenderFn<HTMLProps, {}> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Plus every <div> prop. Source: content-editor/components/content-renderer.tsx.