A lightweight, dependency-free React editor.
npm install @bytecrate/react-editorA lightweight, robust, and feature-rich React email template editor. Built with native contentEditable APIs for maximum compatibility and minimal bundle size.
* Rich Text Formatting: Bold, Italic, Underline, Strikethrough, Heading levels.
* Typography Control: Font Family selection and precise Font Size (px) control.
* Styling: Text color picker with presets and custom color support.
* Layout: Advanced padding controls for individual sides (Top, Right, Bottom, Left) on specific blocks.
* Structure: Ordered and Unordered lists, Blockquotes.
* Media & Links: Image insertion via URL, File Upload (Base64 default, custom async upload supported), and Hyperlink management.
* Templating: Built-in Variable/Merge Tag insertion support (e.g., {{firstName}}).
* History: Undo/Redo functionality.
* Zero Styles Configuration: Works out of the box with internal styling, but accepts external classes.
``bash`
npm install @bytecrate/react-editoror
yarn add @bytecrate/react-editor
`tsx
import React, { useState } from 'react';
import { EmailEditor } from '@bytecrate/react-editor';
const MyEmailApp = () => {
const [htmlContent, setHtmlContent] = useState('');
return (
Hello there,
"{htmlContent}export default MyEmailApp;
`
By default, images selected from the device are converted to Base64 strings. To upload images to a server (e.g., AWS S3, Cloudinary) and use the resulting URL, provide the onImageUpload prop.
`tsx`
// Example: Upload file to your server
const formData = new FormData();
formData.append('image', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
return data.url; // Return the hosted image URL
}}
/>
You can pass a custom list of variables (merge tags) that appear in the {} toolbar dropdown.
`tsx
const myVariables = [
{ label: 'User Name', value: '{{user.name}}' },
{ label: 'Order ID', value: '{{order.id}}' },
{ label: 'Unsubscribe', value: '{{unsubscribe_url}}' }
];
onChange={handleChange}
/>
`
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| initialValue | string | "" | The initial HTML content of the editor. |onChange
| | (html: string) => void | - | Callback fired whenever content changes. |variables
| | Array<{ label: string, value: string }> | DEFAULT_VARIABLES | Array of variables for the insert dropdown. |placeholder
| | string | "Start writing..." | Placeholder text shown when empty. |defaultPadding
| | string | "24px" | Default padding applied to the main container. |onImageUpload
| | (file: File) => Promise | - | Callback to handle custom image uploads (overrides Base64). |style
| | React.CSSProperties | - | Inline styles for the outer editor container. |className
| | string | ""` | CSS class names for the outer editor container. |
This package relies on lucide-react for its icons, which is installed automatically as a dependency.
MIT