0
# Editor Enhancements
1
2
Higher-order functions that enhance the Plate editor with image-specific functionality including upload handling and URL embedding.
3
4
## Capabilities
5
6
### Main Image Enhancement
7
8
Combines upload and embed functionality to provide comprehensive image handling capabilities.
9
10
```typescript { .api }
11
/**
12
* Enhances editor with complete image functionality
13
* Combines withImageUpload and withImageEmbed based on plugin configuration
14
* @param editor - Plate editor instance to enhance
15
* @param plugin - Plugin configuration with ImagePlugin options
16
* @returns Enhanced editor with image capabilities
17
*/
18
function withImage<
19
V extends Value = Value,
20
E extends PlateEditor<V> = PlateEditor<V>
21
>(
22
editor: E,
23
plugin: WithPlatePlugin<ImagePlugin, V, E>
24
): E;
25
```
26
27
**Usage Examples:**
28
29
```typescript
30
import { withImage, ImagePlugin } from "@udecode/plate-image";
31
import { createPlateEditor } from "@udecode/plate-core";
32
33
// Automatically applied through createImagePlugin
34
const editor = createPlateEditor({
35
plugins: [
36
createImagePlugin({
37
options: {
38
uploadImage: async (dataUrl) => uploadToServer(dataUrl),
39
disableUploadInsert: false,
40
disableEmbedInsert: false,
41
}
42
})
43
]
44
});
45
46
// Manual application (advanced usage)
47
let enhancedEditor = createPlateEditor();
48
enhancedEditor = withImage(enhancedEditor, {
49
options: {
50
uploadImage: async (dataUrl) => await customUpload(dataUrl)
51
}
52
});
53
```
54
55
### Image Upload Enhancement
56
57
Enables clipboard and drag-and-drop image upload functionality with optional custom upload handling.
58
59
```typescript { .api }
60
/**
61
* Enhances editor with image upload capabilities from clipboard and drag-and-drop
62
* Intercepts insertData to handle image files and process them through upload pipeline
63
* @param editor - Plate editor instance to enhance
64
* @param plugin - Plugin configuration with upload options
65
* @returns Enhanced editor with upload capabilities
66
*/
67
function withImageUpload<
68
V extends Value = Value,
69
E extends PlateEditor<V> = PlateEditor<V>
70
>(
71
editor: E,
72
plugin: WithPlatePlugin<ImagePlugin, V, E>
73
): E;
74
```
75
76
**Upload Process:**
77
78
1. **File Detection**: Monitors `insertData` calls for image file types
79
2. **MIME Type Validation**: Checks file MIME type starts with 'image/'
80
3. **File Reading**: Uses FileReader to convert files to data URLs
81
4. **Custom Upload**: Calls `uploadImage` function if provided
82
5. **Image Insertion**: Inserts processed image into editor
83
84
**Usage Examples:**
85
86
```typescript
87
import { withImageUpload } from "@udecode/plate-image";
88
89
// Basic upload enhancement
90
const editor = withImageUpload(baseEditor, {
91
options: {
92
uploadImage: async (dataUrl) => {
93
// Upload to your preferred service
94
const formData = new FormData();
95
formData.append('image', dataUrlToBlob(dataUrl));
96
97
const response = await fetch('/api/upload', {
98
method: 'POST',
99
body: formData
100
});
101
102
const result = await response.json();
103
return result.imageUrl;
104
}
105
}
106
});
107
108
// Multiple file handling
109
const multiUploadEditor = withImageUpload(baseEditor, {
110
options: {
111
uploadImage: async (dataUrl) => {
112
try {
113
return await uploadImageWithProgress(dataUrl, {
114
onProgress: (percent) => console.log(`Upload: ${percent}%`)
115
});
116
} catch (error) {
117
console.error('Upload failed, using data URL fallback');
118
return dataUrl; // Fallback to data URL
119
}
120
}
121
}
122
});
123
```
124
125
### Image URL Embedding Enhancement
126
127
Enables automatic conversion of pasted image URLs into image elements.
128
129
```typescript { .api }
130
/**
131
* Enhances editor with automatic image URL embedding
132
* Intercepts insertData to detect image URLs and convert them to image elements
133
* @param editor - Plate editor instance to enhance
134
* @param plugin - Plugin configuration (options not currently used)
135
* @returns Enhanced editor with URL embedding capabilities
136
*/
137
function withImageEmbed<
138
V extends Value = Value,
139
E extends PlateEditor<V> = PlateEditor<V>
140
>(
141
editor: E,
142
plugin: WithPlatePlugin<ImagePlugin, V, E>
143
): E;
144
```
145
146
**Embedding Process:**
147
148
1. **URL Detection**: Monitors pasted text for valid URLs
149
2. **Image URL Validation**: Uses `isImageUrl` to check if URL points to an image
150
3. **Element Creation**: Converts valid image URLs to image elements
151
4. **Insertion**: Inserts image element at current cursor position
152
153
**Usage Examples:**
154
155
```typescript
156
import { withImageEmbed } from "@udecode/plate-image";
157
158
// Basic embed enhancement
159
const editor = withImageEmbed(baseEditor, { options: {} });
160
161
// Combined with upload functionality
162
let fullEditor = createPlateEditor();
163
fullEditor = withImageUpload(fullEditor, {
164
options: {
165
uploadImage: customUploadFunction
166
}
167
});
168
fullEditor = withImageEmbed(fullEditor, { options: {} });
169
170
// Disable embed selectively
171
const noEmbedEditor = withImage(baseEditor, {
172
options: {
173
disableEmbedInsert: true, // URLs won't be auto-embedded
174
disableUploadInsert: false // File uploads still work
175
}
176
});
177
```
178
179
## Enhanced Editor Behavior
180
181
### Data Transfer Handling
182
183
The enhancements intercept the editor's `insertData` method to provide custom handling:
184
185
```typescript
186
// Original insertData behavior is preserved as fallback
187
const originalInsertData = editor.insertData;
188
189
editor.insertData = (dataTransfer: DataTransfer) => {
190
// Custom image handling logic
191
const text = dataTransfer.getData('text/plain');
192
const files = dataTransfer.files;
193
194
// Handle files (withImageUpload)
195
if (files && files.length > 0) {
196
// Process image files...
197
return;
198
}
199
200
// Handle URLs (withImageEmbed)
201
if (isImageUrl(text)) {
202
insertImage(editor, text);
203
return;
204
}
205
206
// Fallback to original behavior
207
originalInsertData(dataTransfer);
208
};
209
```
210
211
### Error Handling Patterns
212
213
```typescript
214
// Robust upload configuration with error handling
215
const robustUploadConfig = {
216
uploadImage: async (dataUrl: string | ArrayBuffer) => {
217
try {
218
// Attempt cloud upload
219
const cloudUrl = await uploadToCloud(dataUrl);
220
return cloudUrl;
221
} catch (cloudError) {
222
console.warn('Cloud upload failed, trying fallback:', cloudError);
223
224
try {
225
// Attempt fallback service
226
const fallbackUrl = await uploadToFallback(dataUrl);
227
return fallbackUrl;
228
} catch (fallbackError) {
229
console.error('All uploads failed, using data URL:', fallbackError);
230
// Use data URL as last resort
231
return dataUrl;
232
}
233
}
234
}
235
};
236
```
237
238
### Configuration Patterns
239
240
```typescript
241
// Environment-specific configuration
242
function createImageEnhancements(environment: 'development' | 'production') {
243
const baseConfig = {
244
disableUploadInsert: false,
245
disableEmbedInsert: false,
246
};
247
248
if (environment === 'development') {
249
return {
250
...baseConfig,
251
uploadImage: (dataUrl: string | ArrayBuffer) => {
252
// Development: just use data URLs
253
console.log('Dev mode: using data URL');
254
return Promise.resolve(dataUrl);
255
}
256
};
257
}
258
259
return {
260
...baseConfig,
261
uploadImage: async (dataUrl: string | ArrayBuffer) => {
262
// Production: upload to CDN
263
return await uploadToCDN(dataUrl);
264
}
265
};
266
}
267
```