plate
examplemultiple-editors-demosource: ok · hit
Multiple Editors Demo
npx shadcn add "https://platejs.org/r/multiple-editors-demo.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · light@platejs/basic-nodes@platejs/basic-nodes@platejs/media
Registry dependencies
separatorhttps://platejs.org/r/basic-nodes-kit.jsonhttps://platejs.org/r/media-kit.jsonhttps://platejs.org/r/editor.jsonhttps://platejs.org/r/fixed-toolbar.jsonhttps://platejs.org/r/turn-into-toolbar-button.json
Files4 · source cached 10/8/2026, 3:39:33 PM
src/registry/examples/multiple-editors-demo.tsx
'use client';
import * as React from 'react';
import { Plate, usePlateEditor } from 'platejs/react';
import { Separator } from '@/components/ui/separator';
import { BasicNodesKit } from '@/registry/components/editor/plugins/basic-nodes-kit';
import { MediaKit } from '@/registry/components/editor/plugins/media-kit';
import { basicBlocksValue } from '@/registry/examples/values/basic-blocks-value';
import { basicMarksValue } from '@/registry/examples/values/basic-marks-value';
import { imageValue } from '@/registry/examples/values/media-value';
import { Editor, EditorContainer } from '@/registry/ui/editor';
import { FixedToolbar } from '@/registry/ui/fixed-toolbar';
import { TurnIntoToolbarButton } from '@/registry/ui/turn-into-toolbar-button';
export default function MultipleEditorsDemo() {
const editor = usePlateEditor({
id: 'editor1',
plugins: BasicNodesKit,
value: basicBlocksValue,
});
const editorMarks = usePlateEditor({
id: 'marks',
plugins: BasicNodesKit,
value: basicMarksValue,
});
const editorImage = usePlateEditor({
id: 'image',
plugins: [...BasicNodesKit, ...MediaKit],
value: imageValue,
});
return (
<Plate editor={editor}>
<Plate editor={editorMarks}>
<Plate editor={editorImage}>
<FixedToolbar>
<TurnIntoToolbarButton />
</FixedToolbar>
<div>
<EditorContainer>
<Editor />
</EditorContainer>
<Separator />
<EditorContainer>
<Editor id="marks" />
</EditorContainer>
<Separator />
<EditorContainer>
<Editor id="image" />
</EditorContainer>
</div>
</Plate>
</Plate>
</Plate>
);
}
src/registry/examples/values/basic-blocks-value.tsx
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from '@platejs/test-utils';
import { KEYS } from 'platejs';
jsx;
export const basicBlocksValue: any = (
<fragment>
<hh1>Heading 1</hh1>
<hp>
This is a top-level heading, typically used for main titles and major
section headers.
</hp>
<hh2>Heading 2</hh2>
<hp>
Secondary headings help organize content into clear sections and
subsections.
</hp>
<hh3>Heading 3</hh3>
<hp>
Third-level headings provide further content structure and hierarchy.
</hp>
<hblockquote>
<hp>
Blockquotes can group multiple paragraphs, quoted lists, and replies in
one container.
</hp>
<hp>
Use nested blockquotes when you need to keep the quote hierarchy
explicit.
</hp>
<hblockquote>
<hp>Nested blockquotes keep reply chains readable.</hp>
</hblockquote>
</hblockquote>
<hp>
Use headings to create a clear document structure that helps readers
navigate your content effectively. Combine them with blockquotes to
emphasize important information.
</hp>
<element type={KEYS.hr}>
<htext />
</element>
<hp>
Horizontal rules help visually separate different sections of your
content, creating clear breaks between topics or ideas.
</hp>
</fragment>
);
src/registry/examples/values/basic-marks-value.tsx
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from '@platejs/test-utils';
jsx;
export const basicMarksValue: any = (
<fragment>
<hh2>Text Formatting</hh2>
<hp>
Add style and emphasis to your text using various formatting options.
</hp>
<hp>
Make text <htext bold>bold</htext>, <htext italic>italic</htext>,{' '}
<htext underline>underlined</htext>, or apply a{' '}
<htext bold italic underline>
combination
</htext>{' '}
of these styles for emphasis.
</hp>
<hp>
Add <htext strikethrough>strikethrough</htext> to indicate deleted
content, use <htext code>inline code</htext> for technical terms, or{' '}
<htext highlight>highlight</htext> important information.
</hp>
<hp>
Format mathematical expressions with <htext subscript>subscript</htext>{' '}
and <htext superscript>superscript</htext> text.
</hp>
<hp>
Show keyboard shortcuts like <htext kbd>⌘ + B</htext> for bold or{' '}
<htext kbd>⌘ + I</htext> for italic formatting.
</hp>
</fragment>
);
src/registry/examples/values/media-value.tsx
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from '@platejs/test-utils';
jsx;
export const imageValue: any = (
<fragment>
<hh2>Image</hh2>
<hp>Add images by either uploading them or providing the image URL:</hp>
<himg
align="center"
caption={[{ children: [{ text: 'Image caption' }] }]}
url="https://images.unsplash.com/photo-1712688930249-98e1963af7bd?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
width="55%"
>
<htext />
</himg>
<hp>Customize image captions and resize images.</hp>
</fragment>
);
export const mediaPlaceholderValue: any = (
<fragment>
<hh2>Upload</hh2>
<hp>
Our editor supports various media types for upload, including images,
videos, audio, and files.
</hp>
<hfile
name="sample.pdf"
align="center"
url="https://s26.q4cdn.com/900411403/files/doc_downloads/test.pdf"
width="80%"
isUpload
>
<htext />
</hfile>
<hp indent={1} listStyleType="disc">
Real-time upload status and progress tracking
</hp>
<haudio
align="center"
url="https://samplelib.com/lib/preview/mp3/sample-3s.mp3"
width="80%"
>
<htext />
</haudio>
<hp indent={1} listStyleType="disc">
Configurable file size limits and batch upload settings
</hp>
<hvideo
align="center"
url="https://videos.pexels.com/video-files/6769791/6769791-uhd_2560_1440_24fps.mp4"
width="80%"
isUpload
>
<htext />
</hvideo>
<hp indent={1} listStyleType="disc">
Clear error messages for any upload issues
</hp>
<hp indent={1} listStyleType="disc">
Try it now - drag an image from your desktop or click the upload button in
the toolbar
</hp>
</fragment>
);
export const mediaValue: any = (
<fragment>
{imageValue}
{mediaPlaceholderValue}
<hh2>Embed</hh2>
<hp>Embed various types of content, such as videos and tweets:</hp>
<hmediaembed
align="center"
url="https://www.youtube.com/watch?v=MyiBAziEWUA"
>
<htext />
</hmediaembed>
{/* BUG */}
{/* <hmediaembed
align="center"
url="https://twitter.com/zbeyens/status/1677214892212776960"
>
<htext />
</hmediaembed> */}
</fragment>
);