Unlayer compatibility
Getting startedUnlayer-compatible data
react-email-craft exposes the same component, props, and ref API as react-email-editor, and reads its design JSON, so your existing designs load and render with no rework.
- import EmailEditor, { type EditorRef, type EmailEditorProps } from "react-email-editor";
+ import EmailEditor, { type EditorRef, type EmailEditorProps } from "react-email-craft";
<EmailEditor ref={emailEditorRef} onLoad={onLoad} onReady={onReady} options={{ mergeTags }} />The other frameworks swap the same way (vanilla JS also renames its global):
- Vue:
vue-email-editor→vue-email-craft(import { EmailEditor }). - Angular:
angular-email-editor→angular-email-craft. - Vanilla JS: replace Unlayer's
embed.jsscript tag withhttps://unpkg.com/vanilla-email-craft/dist/embed.js; it defines themailkaroglobal, so rename your calls (mailkaro.init,mailkaro.createEditor).
What converts automatically#
- Designs. When you call
loadDesign(), existing Unlayer design JSON is detected and converted to MailKaro's format, rows, columns, and column widths, plus these tools mapped to their MailKaro blocks:text,heading,image,button,divider,menu,social,html,spacer,table,timer, andvideo. Any other tool falls back to a raw-HTML or placeholder block so nothing is lost. - Merge tags. Unlayer's grouped merge-tag arrays/objects passed via
options.mergeTagsare flattened to MailKaro's format automatically. Nested groups becomeGroup · Taglabels. Tags inside text render as editable pills.
saveDesign() returns MailKaro's native schema, so from then on the design is stored in MailKaro's own format (a one-way migration: Unlayer JSON in, MailKaro JSON out, with the same output). Designs not re-saved yet still render on your server: renderDesign, renderMjml and the other email-craft-sdk render functions take Unlayer JSON as is, and unlayerDesignToMailkaro converts one explicitly.Ref API parity#
These Unlayer calls work unchanged:
Calls made before the editor is ready (from onLoad, or right after creating it) are queued and run once it is. exportHtml also returns Unlayer's chunks (body, css) and takes its mergeTags option. An image callback gets the file with Unlayer's attachments, and may report progress with done({ progress }) before done({ progress: 100, url }). exportImage and exportPdf answer with Unlayer's no-export shape (url: null); render those on your server with email-craft-sdk. registerTool and createViewer add your own blocks (see Custom tools). Other Unlayer methods (setDesignId, registerProvider, ...) are accepted and have no effect.
Unlayer's displayConditions option and setDisplayConditions work: a row's settings get a Display condition picker, and the chosen condition's before and after go around the row in the exported HTML (and MJML), so your sending tool decides who sees it. Designs saved by Unlayer keep the conditions on their rows and blocks. A preview rendered with merge data shows the content without them. Unlayer's features.textEditor.customButtons work too: each button shows in the text toolbar, and its onAction({ text }, done) runs on your page with the selected words; done(text) puts the result in their place.
mailkaro.init({
id: "editor",
displayConditions: [
{ type: "Plan", label: "Pro customers", description: "Only the Pro plan", before: "{% if plan == 'pro' %}", after: "{% endif %}" }
],
features: {
textEditor: {
customButtons: [{ name: "shout", text: "Shout", icon: "S", onAction: (data, done) => done(data.text.toUpperCase()) }]
}
}
});Events and layout#
onLoad(Vue and Angular:load/loaded) fires when the editor is created, thenonReady(ready) when it has loaded.design:loadedfires with{ design }for the opening design and afterloadDesign/loadBlank;design:updatedfires for edits (with Unlayer's changetype), not for loading a design.- Like Unlayer, there is one listener per event name: adding another for the same name replaces it.
- The component lays out like Unlayer's: React and Angular grow to fill a flex parent; Vue, like vue-email-editor, is
minHeighttall unless you size it withstyle.minHeightdefaults to 500px,editorIdnames the container andstyleapplies to it.
projectId, appearance, tools, scriptUrl) are accepted for parity but ignored. MailKaro is styled and configured through its own config and embed token.New to the API? See the Editor component reference.