Overview
The getEmail method converts Yoopta editor content into email-compatible HTML with proper structure, inline styles, and table-based layout. It’s designed specifically for email clients which have limited CSS support.
Usage
import { useYooptaEditor } from '@yoopta/editor';
function SendEmailButton() {
const editor = useYooptaEditor();
const handleSend = async () => {
const emailHtml = editor.getEmail(editor.children);
await sendEmail({
to: '[email protected]',
subject: 'Your document',
html: emailHtml,
});
};
return <button onClick={handleSend}>Send Email</button>;
}
Signature
function getEmail(
editor: YooEditor,
content: YooptaContentValue,
options?: EmailTemplateOptions
): string
Parameters
The editor instance (automatically provided when called as editor.getEmail())
content
YooptaContentValue
required
The content to convert to email HTML. Typically editor.children for current content.
Optional configuration for the email template structure and styling
Returns
string - Complete email-compatible HTML document
Email Template Options
type EmailTemplateOptions = {
head?: {
styles?: StyleElement[]; // Custom CSS styles
meta?: MetaElement[]; // Meta tags
title?: string; // Email title
};
body?: {
attrs?: ElementAttributes; // Body element attributes
};
container?: {
attrs?: ElementAttributes; // Container table attributes
};
customTemplate?: (content: string) => string; // Custom wrapper
};
Default Options
const DEFAULT_OPTIONS: EmailTemplateOptions = {
head: {
meta: [
{ content: 'width=device-width', name: 'viewport' },
{ charset: 'UTF-8' },
{ content: 'IE=edge', 'http-equiv': 'X-UA-Compatible' },
],
},
body: {
attrs: {
style: {
margin: '0 auto',
padding: 0,
width: '900px',
},
},
},
container: {
attrs: {
style: {
margin: '0 auto',
width: '600px',
},
},
},
};
Output Structure
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
<title>Email-Builder</title>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
<meta content="width=device-width" name="viewport">
<!-- Additional meta tags and styles -->
</head>
<body id="yoopta-email" style="margin: 0 auto; padding: 0; width: 900px;">
<table style="margin: 0 auto; width: 600px;">
<tbody>
<tr>
<td>
<!-- Email content here -->
</td>
</tr>
</tbody>
</table>
</body>
</html>
Examples
Basic Email Export
function ExportEmailButton() {
const editor = useYooptaEditor();
const handleExport = () => {
const emailHtml = editor.getEmail(editor.children);
console.log(emailHtml);
};
return <button onClick={handleExport}>Export Email HTML</button>;
}
Custom Styling
function CustomStyledEmail() {
const editor = useYooptaEditor();
const handleExport = () => {
const emailHtml = editor.getEmail(editor.children, {
head: {
title: 'Newsletter',
styles: [
{
id: 'custom-styles',
content: `
body { font-family: 'Helvetica', Arial, sans-serif; }
h1 { color: #2c3e50; }
p { line-height: 1.6; color: #34495e; }
`,
},
],
},
body: {
attrs: {
style: {
backgroundColor: '#f4f4f4',
margin: '0 auto',
padding: '20px',
width: '100%',
},
},
},
container: {
attrs: {
style: {
backgroundColor: '#ffffff',
borderRadius: '8px',
margin: '0 auto',
padding: '30px',
width: '600px',
},
},
},
});
console.log(emailHtml);
};
return <button onClick={handleExport}>Export Styled Email</button>;
}
Custom Template Wrapper
function BrandedEmail() {
const editor = useYooptaEditor();
const handleExport = () => {
const emailHtml = editor.getEmail(editor.children, {
customTemplate: (content) => `
<!DOCTYPE html>
<html>
<head>
<title>Branded Email</title>
</head>
<body>
<div style="background: #f0f0f0; padding: 20px;">
<div style="background: white; max-width: 600px; margin: 0 auto;">
<div style="background: #007bff; color: white; padding: 20px;">
<h1>Company Name</h1>
</div>
<div style="padding: 20px;">
${content}
</div>
<div style="background: #f8f9fa; padding: 20px; text-align: center;">
<p>© 2024 Company Name. All rights reserved.</p>
</div>
</div>
</div>
</body>
</html>
`,
});
console.log(emailHtml);
};
return <button onClick={handleExport}>Export Branded Email</button>;
}
Send via Email API
function SendEmailButton() {
const editor = useYooptaEditor();
const [sending, setSending] = useState(false);
const handleSend = async () => {
setSending(true);
try {
const emailHtml = editor.getEmail(editor.children, {
head: { title: 'Newsletter - January 2024' },
});
await fetch('/api/send-email', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
to: '[email protected]',
subject: 'January Newsletter',
html: emailHtml,
}),
});
alert('Email sent successfully!');
} catch (error) {
alert('Failed to send email');
} finally {
setSending(false);
}
};
return (
<button onClick={handleSend} disabled={sending}>
{sending ? 'Sending...' : 'Send Email'}
</button>
);
}
Newsletter Template
function NewsletterExport() {
const editor = useYooptaEditor();
const exportNewsletter = () => {
return editor.getEmail(editor.children, {
head: {
title: 'Monthly Newsletter',
meta: [
{ content: 'width=device-width, initial-scale=1.0', name: 'viewport' },
{ charset: 'UTF-8' },
],
styles: [
{
content: `
@media only screen and (max-width: 600px) {
.container { width: 100% !important; }
.content { padding: 10px !important; }
}
`,
},
],
},
body: {
attrs: {
style: {
margin: 0,
padding: 0,
backgroundColor: '#f6f6f6',
fontFamily: 'Arial, sans-serif',
},
},
},
container: {
attrs: {
className: 'container',
style: {
width: '600px',
margin: '0 auto',
backgroundColor: '#ffffff',
},
},
},
});
};
const handleExport = () => {
const html = exportNewsletter();
// Download or send
const blob = new Blob([html], { type: 'text/html' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'newsletter.html';
a.click();
};
return <button onClick={handleExport}>Export Newsletter</button>;
}
Preview Email
function EmailPreview() {
const editor = useYooptaEditor();
const [previewHtml, setPreviewHtml] = useState('');
useEffect(() => {
const handleChange = () => {
const html = editor.getEmail(editor.children);
setPreviewHtml(html);
};
handleChange();
editor.on('change', handleChange);
return () => editor.off('change', handleChange);
}, [editor]);
return (
<div className="email-preview">
<h3>Email Preview</h3>
<iframe
srcDoc={previewHtml}
style={{ width: '100%', height: '600px', border: '1px solid #ccc' }}
title="Email Preview"
/>
</div>
);
}
Email-Specific Features
Table-Based Layout
Email HTML uses tables for layout compatibility:
<table style="margin: 0 auto; width: 600px;">
<tbody>
<tr>
<td>
<!-- Content -->
</td>
</tr>
</tbody>
</table>
Inline Styles
All styles are inlined for maximum email client compatibility:
<p style="margin: 0; padding: 10px; color: #333;">
Content here
</p>
XHTML Doctype
Uses XHTML 1.0 Transitional for better email client support:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Plugin Email Serializers
Plugins define email-specific serializers:
const ParagraphPlugin = {
parsers: {
email: {
serialize: (element, text, meta) => {
return `<p style="margin: 0 0 16px 0; line-height: 1.6;">${text}</p>`;
},
},
},
};
Use Cases
- Email Newsletters: Generate HTML for email campaigns
- Notifications: Send formatted notifications via email
- Reports: Email formatted reports to users
- Transactional Emails: Create order confirmations, receipts
- Marketing Emails: Build promotional email content
- Automated Emails: Generate emails from templates
- Email Previews: Preview how content looks in email
Email Client Compatibility
The generated HTML is optimized for:
- Gmail
- Outlook (desktop and web)
- Apple Mail
- Yahoo Mail
- Mobile email clients
Best practices applied:
- Table-based layouts
- Inline CSS styles
- Limited CSS properties
- No external stylesheets
- No JavaScript
- Minimal web fonts
See Also