A React email builder component with drag and drop functionality
npm install email-builder-onlinePowerful, modern email builder with drag-and-drop blocks, live preview, and HTML export. Built with React and Material UI, distributed as a React component and as a Web Component so it can be embedded in other frameworks (Nuxt 3, Next.js, SvelteKit, etc.). Compatible with React 18 and 19.
π Live Demo
- Drag-and-drop blocks: Text (Rich Text Editor), Heading, Image, Button, Columns, Divider, Spacer, Avatar, HTML, Social Media, Container
- Editor and Preview tabs with responsive screen sizes (Desktop/Mobile)
- Undo/Redo and keyboard shortcuts
- HTML export and copy-to-clipboard helpers
- CSS size guard for email client compatibility
- Dark mode support
- Internationalization (i18n) with English, Spanish, and Italian support
- Works as React component or Web Component - embed in any framework (Nuxt 3, Next.js, SvelteKit, Vue, etc.)
- Built with TypeScript for better developer experience
- Responsive design that works on mobile and desktop
Install the package and its peer dependencies:
``bashFor React applications
npm i email-builder-online react react-dom react-dnd react-dnd-html5-backend i18next react-i18next i18next-browser-languagedetectoror
yarn add email-builder-online react react-dom react-dnd react-dnd-html5-backend i18next react-i18next i18next-browser-languagedetectoror
pnpm add email-builder-online react react-dom react-dnd react-dnd-html5-backend i18next react-i18next i18next-browser-languagedetector
> Note:
> - Material UI (@mui/material) is bundled with the package, so you don't need to install it separately.
> - i18n dependencies (
i18next, react-i18next, i18next-browser-languagedetector) are required for internationalization support and must be installed in your project.Add the stylesheet (required):
`ts
// React / Vite / Nuxt / Next
import 'email-builder-online/style.css';
`Available Blocks
The email builder includes the following drag-and-drop blocks:
- Text - Rich text editor with formatting options (uses CustomEditor)
- Heading - Heading block for titles and subtitles
- Image - Image block with link support
- Button - Call-to-action button with customizable styling
- Columns - Multi-column layout container
- Divider - Horizontal divider/separator line
- Spacer - Vertical spacing block
- Avatar - Profile picture/avatar image
- HTML - Raw HTML block for custom code
- Social Media - Social media icons with links
- Container - Container block for grouping content
Usage
There are two ways to use the builder:
$3
`tsx
import React from 'react';
import { EmailBuilder } from 'email-builder-online';
import 'email-builder-online/style.css';export default function Page() {
return (
primaryColor="#0d9488"
secondaryColor="#0ea5a6"
darkMode={false}
stickyHeader
locale="en"
height="calc(100vh - 80px)"
/>
);
}
`$3
For Web Component usage, you need to set up i18n in your application. Here's how to do it in different frameworks:
#### Nuxt 3 Example
1. First, create an i18n configuration file:
`ts
// plugins/i18n.client.ts
export default defineNuxtPlugin(() => {
const i18n = {
// Your i18n configuration
fallbackLng: 'en',
debug: false,
interpolation: {
escapeValue: false,
},
resources: {
en: {
translation: {
// Your English translations
}
},
es: {
translation: {
// Your Spanish translations
}
}
}
};
// Make i18n available globally
return {
provide: {
i18n
}
};
});
`2. Then register the email builder component:
`ts
// plugins/email-builder.client.ts
import { registerEmailBuilder } from 'email-builder-online';
import 'email-builder-online/style.css';export default defineNuxtPlugin((nuxtApp) => {
// Initialize i18n
const i18n = nuxtApp.$i18n; // Your i18n instance
// Register the web component with i18n support
registerEmailBuilder('email-builder', { i18n });
});
`#### Vanilla JavaScript Example
`html
`Then use it anywhere in your templates (wrap in
for Nuxt):`vue
primary-color="#0d9488"
secondary-color="#0ea5a6"
dark-mode="false"
sticky-header="true"
locale="en"
height="calc(100vh - 80px)"
/>
`For Vue/Nuxt, you can silence unknown element warnings by marking the tag as a custom element:
`ts
// nuxt.config.ts
export default defineNuxtConfig({
vue: {
compilerOptions: {
isCustomElement: (tag) => tag === 'email-builder',
},
},
css: ['email-builder-online/style.css'],
});
`Notes on SSR and dependencies:
- The Web Component wrapper is registered only on the client. Use a client-only plugin in SSR frameworks.
- React and ReactDOM are peer dependencies even for the Web Component. Install them in your app or use a bundler that provides them. React 18 and 19 are supported.
Custom Editor Standalone
The package also ships the
CustomEditorInputStandalone component so the rich text block can be embedded outside of the full builder experience.$3
`tsx
import { useState } from 'react';
import { CustomEditorInputStandalone } from 'email-builder-online';
import 'email-builder-online/style.css';export default function CustomEditorExample() {
const [value, setValue] = useState('
Write your custom content hereβ¦
'); return (
initialData={value}
onChange={setValue}
editorBackgroundColor="#ffffff"
editorColorDefault="#1f2937"
fontFamily="MODERN_SANS"
lineHeight={1.6}
/>
);
}
`$3
`ts
import { registerCustomEditorInput } from 'email-builder-online';
import 'email-builder-online/style.css';if (typeof window !== 'undefined') {
registerCustomEditorInput('custom-editor'); // default is "custom-editor-input"
}
`Props / Attributes
React Props (camelCase) and Web Component attributes (dash-case) map 1:1:
| React Prop | Web Component Attribute | Type | Default | Description |
|------------|------------------------|------|---------|-------------|
| primaryColor | primary-color | string | #058705 | Primary theme color |
| secondaryColor | secondary-color | string | #079707 | Secondary theme color |
| darkMode | dark-mode | boolean | false | Enable dark mode |
| height | height | string | - | Container height (e.g. "calc(100vh - 80px)") |
| stickyHeader | sticky-header | boolean | true | Sticky header behavior |
| sticky | sticky | boolean | false | Sticky content behavior |
| galleryImages | gallery-images | boolean | false | Enable image gallery |
| locale | locale | string | - | UI language (en, es, it, en-US, es-419, it-IT). Falls back to dataLocale if not provided |
| dataLocale | data-locale | string | - | Alternative locale prop (used as fallback if locale is not provided) |
| htmlTab | html-tab | boolean | true | Show HTML tab |
| jsonTab | json-tab | boolean | true | Show JSON tab |
| imagePlaceholder | image-placeholder | string | - | Default placeholder for images |
Internationalization (i18n)
The builder supports multiple languages. Pass the
locale prop with one of the supported values:-
en or en-US - English (default)
- es or es-419 - Spanish
- it or it-IT - Italian`tsx
`TypeScript
Types are shipped. You can import them as:
`ts
import type { EmailBuilderProps } from 'email-builder-online';
``MIT Β© Laravel42
- π Website: laravel42.com
- π¦ More Open Source: npmjs.com/~laravel42
- πΌ LinkedIn: Laravel42
- π Facebook: Laravel42
- πΈ Instagram: @laravel42_
See Git history for details. Please open issues or PRs for bugs and improvements.