A React email editor library that bundles React 18 internally and can run in React 19 applications.
- 🔗 React 18 Bundled: The library includes React 18 internally, allowing it to run independently of the host application's React version
- 🚀 React 19 Compatible: Can be used in React 19 applications without conflicts
- ✨ Isolated Rendering: Uses isolated React roots to prevent version conflicts
- 📧 Email Editor: Full-featured email template editor based on easy-email-editor
yarn add @wordup/email-editor
# or
npm install @wordup/email-editorimport { mountEmailEditor, unmountEmailEditor } from "@wordup/email-editor";
import { useEffect } from "react";
function EmailEditorComponent() {
useEffect(() => {
// Mount the email editor with React 18
mountEmailEditor("email-editor-container", {
height: "100vh",
onTemplateChange: (template) => {
console.log("Template changed:", template);
},
onUploadImage: async (blob) => {
// Handle image upload
return "https://example.com/uploaded-image.jpg";
},
});
// Cleanup on unmount
return () => {
unmountEmailEditor();
};
}, []);
return (
<div
id="email-editor-container"
style={{ width: "100%", height: "100vh" }}
/>
);
}import { mountEmailEditor, unmountEmailEditor } from '@wordup/email-editor'
// Mount with full configuration
mountEmailEditor('editor-container', {
data: {
subject: 'Welcome Email',
subTitle: 'Get started with our platform',
content: {
type: 'page',
data: {},
attributes: {},
children: []
}
},
height: '800px',
autoComplete: true,
dashed: false,
compact: false,
showSourceCode: true,
fontList: [
{ value: 'Arial', label: 'Arial' },
{ value: 'Helvetica', label: 'Helvetica' }
],
categories: [
{ label: 'Content', blocks: [...] },
{ label: 'Layout', blocks: [...] }
],
onTemplateChange: (template) => {
// Save template
console.log('Template updated:', template)
},
onBeforePreview: (html) => {
// Modify HTML before preview
return html
},
onUploadImage: async (blob) => {
// Upload image to your server
const formData = new FormData()
formData.append('image', blob)
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
})
const { url } = await response.json()
return url
}
})Mounts the email editor in the specified DOM element.
Parameters:
id: The ID of the DOM element where the editor will be mountedprops: Configuration options for the editor
Unmounts the email editor and cleans up resources.
interface IsolatedEmailEditorProps {
data?: IEmailTemplate;
height?: string;
autoComplete?: boolean;
dashed?: boolean;
fontList?: Array<{ value: string; label: string }>;
onBeforePreview?: (html: string) => string;
onUploadImage?: (data: Blob) => Promise<string>;
onTemplateChange?: (template: IEmailTemplate) => void;
categories?: any[];
compact?: boolean;
showSourceCode?: boolean;
}This library uses a unique approach to solve React version conflicts:
- Bundled React 18: The library includes its own copy of React 18
- Isolated Mounting: Uses React 18's
createRootAPI to mount in an isolated DOM node - Global State Management: Uses
window.emaileditorto manage the React root globally - Version Independence: Can run alongside React 19 without conflicts
Run nx test @wordup/email-editor to execute the unit tests via Vitest.
Run nx build @wordup/email-editor to build the library.
MIT