Comprehensive media handling capabilities for the Plate rich text editor framework, supporting images, videos, audio files, and embeddable content
npx @tessl/cli install tessl/npm-udecode--plate-media@49.0.0Plate Media provides comprehensive media handling capabilities for the Plate rich text editor framework, enabling developers to embed and manage various types of media content including images, videos (YouTube, Vimeo), audio files, generic files, and embeddable content like tweets. The plugin offers a modular architecture with support for placeholder handling during media loading, media embedding with URL parsing, resizable media components, and caption functionality.
npm install @udecode/plate-mediaimport {
BaseImagePlugin,
BaseVideoPlugin,
BaseAudioPlugin,
BaseFilePlugin,
BaseMediaEmbedPlugin,
BasePlaceholderPlugin,
insertImage,
insertImageFromFiles,
insertMediaEmbed,
isImageUrl,
parseVideoUrl,
parseTwitterUrl
} from "@udecode/plate-media";React components and hooks:
import {
ImagePlugin,
VideoPlugin,
AudioPlugin,
FilePlugin,
MediaEmbedPlugin,
PlaceholderPlugin,
openImagePreview,
useImagePreview,
useMediaState
} from "@udecode/plate-media/react";For CommonJS:
const {
BaseImagePlugin,
BaseVideoPlugin,
BaseAudioPlugin,
BaseFilePlugin
} = require("@udecode/plate-media");import {
BaseImagePlugin,
BaseMediaEmbedPlugin,
insertImage,
insertMediaEmbed
} from "@udecode/plate-media";
import { createSlateEditor } from "@udecode/plate";
// Create editor with media plugins
const editor = createSlateEditor({
plugins: [
BaseImagePlugin.configure({
options: {
uploadImage: async (file) => {
// Upload logic here
return "https://example.com/uploaded-image.jpg";
}
}
}),
BaseMediaEmbedPlugin
]
});
// Insert an image
insertImage(editor, "https://example.com/image.jpg");
// Insert a media embed
insertMediaEmbed(editor, {
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
});Plate Media is built around several key components:
Core Slate plugins that provide the foundation for all media handling. Each plugin defines element types, configurations, and basic transforms.
const BaseImagePlugin: TSlatePlugin<ImageConfig>;
const BaseVideoPlugin: TSlatePlugin<VideoConfig>;
const BaseAudioPlugin: TSlatePlugin<AudioConfig>;
const BaseFilePlugin: TSlatePlugin<FileConfig>;Complete image management including upload, embed detection, preview functionality, and resizing capabilities.
function insertImage(
editor: SlateEditor,
url: ArrayBuffer | string,
options?: InsertNodesOptions
): void;
function insertImageFromFiles(
editor: SlateEditor,
files: FileList,
options?: InsertNodesOptions
): void;
function isImageUrl(url: string): boolean;Support for embedding videos and social media content from major providers including YouTube, Vimeo, Twitter, and more.
const BaseMediaEmbedPlugin: TSlatePlugin<MediaEmbedConfig>;
function insertMediaEmbed(
editor: SlateEditor,
{ url = '' }: Partial<TMediaEmbedElement>,
options?: InsertNodesOptions
): void;
function parseVideoUrl(url: string): EmbedUrlData | undefined;
function parseTwitterUrl(url: string): EmbedUrlData | undefined;Advanced placeholder-based upload system with file validation, progress tracking, and error handling.
const BasePlaceholderPlugin: TSlatePlugin<PlaceholderConfig>;
function insertPlaceholder(
editor: SlateEditor,
mediaType: string,
options?: InsertNodesOptions
): void;
interface UploadConfig {
[K in AllowedFileType]?: MediaItemConfig;
}
interface MediaItemConfig {
mediaType: MediaKeys;
maxFileCount?: number;
maxFileSize?: FileSize;
minFileCount?: number;
}React integration providing UI components, hooks, and state management for media interactions.
const ImagePlugin: TPlatePlugin<ImageConfig>;
const MediaEmbedPlugin: TPlatePlugin<MediaEmbedConfig>;
const PlaceholderPlugin: TPlatePlugin<PlaceholderConfig>;
// Image preview functionality
function openImagePreview(editor: SlateEditor, element: TMediaElement): void;
function useImagePreview(options: { scrollSpeed: number }): ImagePreviewControls;
// Media state management
function useMediaState(options?: { urlParsers?: EmbedUrlParser[] }): MediaStateResult;interface EmbedUrlData {
id?: string;
provider?: string;
url?: string;
}
type EmbedUrlParser = (url: string) => EmbedUrlData | undefined;
interface MediaPluginOptions {
isUrl?: (text: string) => boolean;
transformUrl?: (url: string) => string;
}
interface InsertMediaOptions extends InsertNodesOptions {
type?: string;
getUrl?: () => Promise<string>;
}
type AllowedFileType = 'image' | 'video' | 'audio' | 'pdf' | 'text' | 'blob';
type FileSize = `${number}${'B' | 'KB' | 'MB' | 'GB'}`;
interface UploadError {
code: 'INVALID_FILE_TYPE' | 'TOO_MANY_FILES' | 'INVALID_FILE_SIZE' | 'TOO_LESS_FILES' | 'TOO_LARGE';
message: string;
}
interface ImagePreviewControls {
closeProps: { onClick: () => void };
currentUrlIndex: number | null;
maskLayerProps: { onClick: () => void };
nextDisabled: boolean;
nextProps: { disabled: boolean; onClick: () => void };
prevDisabled: boolean;
prevProps: { disabled: boolean; onClick: () => void };
scaleTextProps: { onClick: () => void };
zommOutProps: { disabled: boolean; onClick: () => void };
zoomInDisabled: boolean;
zoomInProps: { disabled: boolean; onClick: () => void };
zoomOutDisabled: boolean;
}