Quick start
Getting startedQuick start
Mount the editor, wire a ref, and read the design back. That's the whole loop.
tsxComposer.tsx
import { useRef } from "react";
import EmailEditor, { type MailkaroIframeEditorRef } from "react-email-craft";
export function Composer() {
const editorRef = useRef<MailkaroIframeEditorRef>(null);
const onReady = () => {
// Load a saved design (or leave empty for a blank canvas)
// editorRef.current?.editor.loadDesign(savedDesign);
};
const save = () => {
editorRef.current?.editor.exportHtml(({ design, html }) => {
// 'design' is JSON you store; 'html' is a preview export
console.log(design, html);
});
};
return (
<div style={{ height: "100vh" }}>
<EmailEditor
ref={editorRef}
token="pk_live_xxx" // scopes plan + features (optional in dev)
options={{ mergeTags: {} }} // field pickers (see Merge tags)
onReady={onReady}
/>
<button onClick={save}>Save</button>
</div>
);
}The default export is the Unlayer-compatible editor. Its ref exposes an
editor object with saveDesign, exportHtml, loadDesign, setMergeTags, and addEventListener, see Methods.The loop in five steps#
- Import the editor. Import EmailEditor from react-email-craft and create a ref with useRef.
- Mount it in a sized container. Render EmailEditor inside an element with a height and pass your pk_live_ token, options and an onReady handler.
- Load a design or start blank. In onReady, call editor.loadDesign with a saved design, or leave it out for a blank canvas.
- Read the design back. Call editor.exportHtml in a save handler. You get the design JSON and a preview of the HTML.
- Store the design JSON. Keep the design JSON in your own database, and render production HTML on your server so merge tags resolve against real data.
What you get back#
- Design JSON, the source of truth; store it and reload it later.
- HTML, a preview export. For production sends, render on the server (see Rendering) so merge tags resolve against real data.
Have existing Unlayer designs? They load automatically.