How to Import Templates
Easy Email Pro supports importing email templates from various formats, allowing you to migrate existing templates or load templates from files.
Supported Formats​
You can import templates from the following formats:
- MJML XML Format - Standard MJML XML files
- MJML JSON Format - MJML data in JSON structure
- Easy Email JSON - Templates from the open-source Easy Email project
- Easy Email Pro JSON - Native Easy Email Pro template format
Implementation​
For complete implementation examples, check our live demo code.
Import Methods​
Import MJML XML​
Import from MJML XML files:
import { useEditorContext } from "easy-email-pro-theme";
import { mjmlToJson } from "easy-email-pro-theme";
import { Uploader } from "@arco-design/web-react";
const { reset } = useEditorContext();
const onImportMJML = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "text/mjml,application/xml",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const pageData = await new Promise<[string, EmailTemplate["content"]]>(
(resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject(new Error("Failed to read file"));
return;
}
try {
// Convert MJML XML to Easy Email Pro format
const pageData = mjmlToJson(evt.target.result as string);
resolve([file.name, pageData]);
} catch (error) {
reject(error);
}
};
reader.readAsText(file);
}
);
// Reset editor with imported template
reset({
subject: pageData[0],
content: pageData[1],
});
};
Import MJML JSON​
Import from MJML JSON format:
const onImportMJMLJSON = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "application/json",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const pageData = await new Promise<[string, EmailTemplate["content"]]>(
(resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject(new Error("Failed to read file"));
return;
}
try {
// Parse JSON and convert to Easy Email Pro format
const mjmlJson = JSON.parse(evt.target.result as string);
const pageData = mjmlToJson(mjmlJson);
resolve([file.name, pageData]);
} catch (error) {
reject(error);
}
};
reader.readAsText(file);
}
);
reset({
subject: pageData[0],
content: pageData[1],
});
};
Import Easy Email Pro JSON​
Import native Easy Email Pro template format:
import { EmailTemplate } from "easy-email-pro-editor";
const onImportJSON = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "application/json",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const emailTemplate = await new Promise<EmailTemplate>(
(resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject(new Error("Failed to read file"));
return;
}
try {
const template = JSON.parse(
evt.target.result as string
) as EmailTemplate;
// Validate template structure
if (!template.content || !template.subject) {
throw new Error("Invalid template format");
}
resolve(template);
} catch (error) {
reject(error);
}
};
reader.readAsText(file);
}
);
reset({
subject: emailTemplate.subject,
content: emailTemplate.content,
});
};
Import Easy Email (Legacy)​
Import templates from the open-source Easy Email project:
import { easyEmailToEasyEmailPro } from "easy-email-pro-core";
import { Message } from "@arco-design/web-react";
const onImportEasyEmailJSON = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "application/json",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const emailTemplate = await new Promise<EmailTemplate>(
(resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject(new Error("Failed to read file"));
return;
}
try {
const template = JSON.parse(evt.target.result as string);
if (!template.content) {
Message.error("Invalid template: content parameter is required");
reject(new Error("Invalid template"));
return;
}
// Convert Easy Email format to Easy Email Pro format
const content = easyEmailToEasyEmailPro(template.content);
resolve({
subject: template.subject || "",
content: content,
});
} catch (error) {
console.error("Import error:", error);
Message.error("Failed to import template");
reject(error);
}
};
reader.readAsText(file);
}
);
reset({
subject: emailTemplate.subject,
content: emailTemplate.content,
});
};
Complete Example​
Here's a complete example with error handling:
import { useEditorContext } from "easy-email-pro-theme";
import { mjmlToJson } from "easy-email-pro-theme";
import { easyEmailToEasyEmailPro } from "easy-email-pro-core";
import { Uploader, Message } from "@arco-design/web-react";
import { EmailTemplate } from "easy-email-pro-editor";
function ImportButtons() {
const { reset } = useEditorContext();
const handleFileUpload = async (
accept: string,
processor: (content: string) => EmailTemplate["content"]
) => {
try {
const uploader = new Uploader(() => Promise.resolve(""), {
accept,
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const result = await new Promise<EmailTemplate["content"]>(
(resolve, reject) => {
reader.onload = (evt) => {
if (!evt.target) {
reject(new Error("Failed to read file"));
return;
}
try {
const content = processor(evt.target.result as string);
resolve(content);
} catch (error) {
reject(error);
}
};
reader.onerror = () => reject(new Error("File read error"));
reader.readAsText(file);
}
);
reset({
subject: file.name,
content: result,
});
Message.success("Template imported successfully");
} catch (error) {
Message.error(`Import failed: ${error.message}`);
}
};
return (
<div>
<Button onClick={() => handleFileUpload(
"text/mjml,application/xml",
(content) => mjmlToJson(content)
)}>
Import MJML XML
</Button>
<Button onClick={() => handleFileUpload(
"application/json",
(content) => {
const json = JSON.parse(content);
return mjmlToJson(json);
}
)}>
Import MJML JSON
</Button>
<Button onClick={() => handleFileUpload(
"application/json",
(content) => {
const template = JSON.parse(content);
return easyEmailToEasyEmailPro(template.content);
}
)}>
Import Easy Email JSON
</Button>
</div>
);
}
Notes​
- Always validate imported templates before resetting the editor
- Handle errors gracefully with user feedback
- The
resetfunction will replace the entire template, so ensure the imported data is valid - MJML imports may require additional validation depending on MJML version compatibility
EditorHeader.tsx
const { values, submit, setFieldValue, mergetagsData, reset, dirty } =
useEditorContext();
const onImportMJML = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "text/mjml",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const pageData = await new Promise<[string, EmailTemplate["content"]]>(
(resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject();
return;
}
try {
const pageData = mjmlToJson(evt.target.result as any);
resolve([file.name, pageData]);
} catch (error) {
reject();
}
};
reader.readAsText(file);
}
);
reset({
subject: pageData[0],
content: pageData[1],
});
};
const onImportMJMLJSON = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "application/json",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const pageData = await new Promise<[string, EmailTemplate["content"]]>(
(resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject();
return;
}
try {
const pageData = mjmlToJson(
JSON.parse(evt.target.result as any) as any
);
resolve([file.name, pageData]);
} catch (error) {
reject();
}
};
reader.readAsText(file);
}
);
reset({
subject: pageData[0],
content: pageData[1],
});
};
const onImportJSON = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "application/json",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const emailTemplate = await new Promise<EmailTemplate>((resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject();
return;
}
try {
const template = JSON.parse(evt.target.result as any) as EmailTemplate;
resolve(template);
} catch (error) {
reject();
}
};
reader.readAsText(file);
});
reset({
subject: emailTemplate.subject,
content: emailTemplate.content,
});
};
const onImportEasyEmailJSON = async () => {
const uploader = new Uploader(() => Promise.resolve(""), {
accept: "application/json",
limit: 1,
});
const [file] = await uploader.chooseFile();
const reader = new FileReader();
const emailTemplate = await new Promise<EmailTemplate>((resolve, reject) => {
reader.onload = function (evt) {
if (!evt.target) {
reject();
return;
}
try {
const template = JSON.parse(evt.target.result as any);
const content = easyEmailToEasyEmailPro(template.content);
if (!template.content) {
Message.error(`Invalid template, need content params`);
reject();
return;
}
resolve({
subject: template.subject,
content: content,
});
} catch (error) {
console.log(error);
reject();
}
};
reader.readAsText(file);
});
reset({
subject: emailTemplate.subject,
content: emailTemplate.content,
});
};