Rendering & export
RenderingRendering & export
A design is JSON. To send it, render it to email-safe HTML on your server with email-craft-sdk, then hand it to any ESP.
import { renderDesign, migrateDesign } from "email-craft-sdk";
app.post("/emails/:id/render", async (req, res) => {
const stored = await db.emails.get(req.params.id); // { design }
const design = migrateDesign(stored.design); // upgrade old schemas safely
const html = renderDesign(design, {
fullDocument: true, // complete <html> email
mergeTags: { first_name: req.query.name ?? "" } // resolve tokens for this recipient
});
res.json({ html }); // send via Postmark / SES / SendGrid / …
});What you can produce#
- HTML,
renderDesign(design, { fullDocument: true, mergeTags }), email-safe across clients. - Design JSON, export/import the raw design (Pro:
editor.export_json). - AMP for Email,
renderAmp(design, { mergeTags }), an interactive AMP4EMAIL document (see below). - Document (print/PDF),
renderDocument(design, { pageSize }), a paged, letter/A4-width sheet the browser can "Save as PDF" (see the page/document builder below). - ZIP bundle,
renderEmailZip(design)packsindex.html, MJML, AMP, plain text, and the design JSON into one downloadable.zip(see below). - MJML / plain text / image / popup overlay, additional outputs from the renderer and Pro export features.
The Export menu & custom exporters#
In the editor, the toolbar Export button downloads any format, HTML, MJML, AMP, plain text, design JSON, or a ZIP bundle. Register your own formats with config.exporters: each exporter turns the design into a file (text or binary), and appears in the menu after the built-ins. Use it to add a PDF service, a CMS payload, or an ESP-specific format without forking the editor.
import { resolveExporters, builtinExporters } from "email-craft-sdk";
const config = {
exporters: [
{
id: "pdf", label: "PDF", extension: "pdf", mimeType: "application/pdf", binary: true, run: async (design) => {
const html = renderDesign(design, { fullDocument: true });
return await myPdfService(html); // returns a Uint8Array
}
}
]
};
// Headless: resolveExporters(config.exporters) → [...builtins, pdf]id matches a built-in (html, zip, …) replaces it, so you can swap in a smarter HTML/PDF pipeline while keeping the same menu.ZIP bundle#
renderEmailZip(design) returns the raw bytes of a valid .zip containing index.html, email.mjml, email.amp.html, email.txt, design.json, and a README. The encoder is dependency-free (works in Node and the browser). In the editor it's the ZIP bundle item in the Export menu; via the ref it's editorRef.current?.editor.exportZip(({ zip }) => …).
Page & document builder#
Set config.builder to "email" (default, ~600px), "page" (wider ~1024px landing page), or "document" (letter-width ~880px with padding). It widens the canvas to match what you're building. For document output, renderDocument(design, { pageSize: "letter" | "a4" }) wraps the same blocks in a paged sheet with an @page rule and print styles, print it to PDF from the browser.
<EmailEditor config={{ builder: "document" }} />
// Server / headless:
import { renderDocument } from "email-craft-sdk";
const html = renderDocument(design, { pageSize: "a4" });migrateDesign() before rendering a stored design, it safely upgrades older schema versions so old saved emails keep rendering.AMP for Email#
renderAmp produces an AMP4EMAIL document, the interactive MIME part you send alongside the HTML fallback. Images become <amp-img> and the carousel block becomes a swipeable <amp-carousel>; the AMP boilerplate, runtime, and any component scripts are included, and all CSS moves into <style amp-custom>.
import { renderAmp } from "email-craft-sdk";
const amp = renderAmp(design, { mergeTags: { first_name: "Sam" } });
// Send as the text/x-amp-html part, with renderDesign(...) as the text/html fallback.
// In the editor: the toolbar "Copy AMP" button, or the ref, editorRef.current?.editor.exportAmp(({ amp }) => sendAmpPart(amp));!important, no <style> in the body, explicit image dimensions). MailKaro emits a structurally-valid document and stacks slides as the HTML fallback; validate the output with amphtml-validator for a given design before you rely on it in production. Gmail also requires senders to register for AMP email.Preview vs. send#
The editor's exportHtml is a convenient preview. For production sends, render server-side with real merge-tag values so personalization is accurate.