Image plugin for Plate rich text editor that enables embedding, uploading, and managing images with advanced features like drag-and-drop, resizing, and captions.
—
Higher-order functions that enhance the Plate editor with image-specific functionality including upload handling and URL embedding.
Combines upload and embed functionality to provide comprehensive image handling capabilities.
/**
* Enhances editor with complete image functionality
* Combines withImageUpload and withImageEmbed based on plugin configuration
* @param editor - Plate editor instance to enhance
* @param plugin - Plugin configuration with ImagePlugin options
* @returns Enhanced editor with image capabilities
*/
function withImage<
V extends Value = Value,
E extends PlateEditor<V> = PlateEditor<V>
>(
editor: E,
plugin: WithPlatePlugin<ImagePlugin, V, E>
): E;Usage Examples:
import { withImage, ImagePlugin } from "@udecode/plate-image";
import { createPlateEditor } from "@udecode/plate-core";
// Automatically applied through createImagePlugin
const editor = createPlateEditor({
plugins: [
createImagePlugin({
options: {
uploadImage: async (dataUrl) => uploadToServer(dataUrl),
disableUploadInsert: false,
disableEmbedInsert: false,
}
})
]
});
// Manual application (advanced usage)
let enhancedEditor = createPlateEditor();
enhancedEditor = withImage(enhancedEditor, {
options: {
uploadImage: async (dataUrl) => await customUpload(dataUrl)
}
});Enables clipboard and drag-and-drop image upload functionality with optional custom upload handling.
/**
* Enhances editor with image upload capabilities from clipboard and drag-and-drop
* Intercepts insertData to handle image files and process them through upload pipeline
* @param editor - Plate editor instance to enhance
* @param plugin - Plugin configuration with upload options
* @returns Enhanced editor with upload capabilities
*/
function withImageUpload<
V extends Value = Value,
E extends PlateEditor<V> = PlateEditor<V>
>(
editor: E,
plugin: WithPlatePlugin<ImagePlugin, V, E>
): E;Upload Process:
insertData calls for image file typesuploadImage function if providedUsage Examples:
import { withImageUpload } from "@udecode/plate-image";
// Basic upload enhancement
const editor = withImageUpload(baseEditor, {
options: {
uploadImage: async (dataUrl) => {
// Upload to your preferred service
const formData = new FormData();
formData.append('image', dataUrlToBlob(dataUrl));
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const result = await response.json();
return result.imageUrl;
}
}
});
// Multiple file handling
const multiUploadEditor = withImageUpload(baseEditor, {
options: {
uploadImage: async (dataUrl) => {
try {
return await uploadImageWithProgress(dataUrl, {
onProgress: (percent) => console.log(`Upload: ${percent}%`)
});
} catch (error) {
console.error('Upload failed, using data URL fallback');
return dataUrl; // Fallback to data URL
}
}
}
});Enables automatic conversion of pasted image URLs into image elements.
/**
* Enhances editor with automatic image URL embedding
* Intercepts insertData to detect image URLs and convert them to image elements
* @param editor - Plate editor instance to enhance
* @param plugin - Plugin configuration (options not currently used)
* @returns Enhanced editor with URL embedding capabilities
*/
function withImageEmbed<
V extends Value = Value,
E extends PlateEditor<V> = PlateEditor<V>
>(
editor: E,
plugin: WithPlatePlugin<ImagePlugin, V, E>
): E;Embedding Process:
isImageUrl to check if URL points to an imageUsage Examples:
import { withImageEmbed } from "@udecode/plate-image";
// Basic embed enhancement
const editor = withImageEmbed(baseEditor, { options: {} });
// Combined with upload functionality
let fullEditor = createPlateEditor();
fullEditor = withImageUpload(fullEditor, {
options: {
uploadImage: customUploadFunction
}
});
fullEditor = withImageEmbed(fullEditor, { options: {} });
// Disable embed selectively
const noEmbedEditor = withImage(baseEditor, {
options: {
disableEmbedInsert: true, // URLs won't be auto-embedded
disableUploadInsert: false // File uploads still work
}
});The enhancements intercept the editor's insertData method to provide custom handling:
// Original insertData behavior is preserved as fallback
const originalInsertData = editor.insertData;
editor.insertData = (dataTransfer: DataTransfer) => {
// Custom image handling logic
const text = dataTransfer.getData('text/plain');
const files = dataTransfer.files;
// Handle files (withImageUpload)
if (files && files.length > 0) {
// Process image files...
return;
}
// Handle URLs (withImageEmbed)
if (isImageUrl(text)) {
insertImage(editor, text);
return;
}
// Fallback to original behavior
originalInsertData(dataTransfer);
};// Robust upload configuration with error handling
const robustUploadConfig = {
uploadImage: async (dataUrl: string | ArrayBuffer) => {
try {
// Attempt cloud upload
const cloudUrl = await uploadToCloud(dataUrl);
return cloudUrl;
} catch (cloudError) {
console.warn('Cloud upload failed, trying fallback:', cloudError);
try {
// Attempt fallback service
const fallbackUrl = await uploadToFallback(dataUrl);
return fallbackUrl;
} catch (fallbackError) {
console.error('All uploads failed, using data URL:', fallbackError);
// Use data URL as last resort
return dataUrl;
}
}
}
};// Environment-specific configuration
function createImageEnhancements(environment: 'development' | 'production') {
const baseConfig = {
disableUploadInsert: false,
disableEmbedInsert: false,
};
if (environment === 'development') {
return {
...baseConfig,
uploadImage: (dataUrl: string | ArrayBuffer) => {
// Development: just use data URLs
console.log('Dev mode: using data URL');
return Promise.resolve(dataUrl);
}
};
}
return {
...baseConfig,
uploadImage: async (dataUrl: string | ArrayBuffer) => {
// Production: upload to CDN
return await uploadToCDN(dataUrl);
}
};
}Install with Tessl CLI
npx tessl i tessl/npm-udecode--plate-image