Getting designs out
Everything your users make can leave Lettrove in seven forms, from your page (the design exactly as on screen) or from your server (the design as last saved).
| You want | From the page | From your server (@lettrove/node) |
|---|---|---|
| The HTML to send or publish | editor.exportHtml() | lettrove.designs.export(id, { user }) |
| The HTML in pieces, for your own page | exportHtml() → chunks | the same → chunks |
| Plain text | editor.exportPlainText() | designs.export → text |
| A PDF | editor.exportPdf() | designs.export(id, { user, format: 'pdf' }) |
| A PNG picture | editor.exportImage() | designs.export(id, { user, format: 'png' }) |
| A ZIP (HTML, text, images) | editor.exportZip() | designs.export(id, { user, format: 'zip' }) |
| The design itself, to keep | editor.getDesign() | lettrove.designs.get(id, { user }) |
Each mode offers what makes sense for it: an email all of them, a popup no PDF. Every export is recorded, and the images it shows are marked as sent, so they are never deleted.
HTML: exportHtml()
const out = await editor.exportHtml({
merge: { contact: { first_name: 'Ada' }, unsubscribeUrl: 'https://acme.com/u/123' }, // optional
text: { links: true, images: true, preheader: false }, // optional
});
| Field | |
|---|---|
html | The whole HTML document, minified, ready to send or host |
chunks | { body, css, js, fonts } — the same HTML in pieces to place inside your own page (Landing page, Popup) |
text | The plain-text version |
subject, preheader | An email's subject and preheader, merged the same way |
mergeTags | Merge tags still in it, exactly as written — fill them before it goes to anyone |
warnings | Anything an inbox would do to it that you should know, e.g. Gmail clipping past ~102 KB |
bytes | The HTML's size |
mode | email, page, popup or document |
designId, revision | Which design, and the saved revision the screen was based on |
exportId | This export's record, for your logs and for support |
rendererVersion | The renderer that made it |
design | The design document, to keep (what you may rely on) |
Without merge, every merge tag stays exactly as written — handy when your own email service fills
them. See Merge tags.
An image your user pasted straight into the design (not uploaded) is uploaded on the way out, so
the HTML only ever points at https:// images: inboxes drop embedded ones.
Plain text: exportPlainText()
const { text } = await editor.exportPlainText({
links: true, // write each link's address beside its label (default true); false keeps labels, drops buttons
images: true, // speak each image by its alt text (default true)
preheader: false,// start with the preheader (default false)
merge: { contact: { first_name: 'Ada' } }, // optional, as for exportHtml
});
Send it as the text/plain part beside the HTML: inboxes that do not show HTML show this, and spam
filters like to see both.
Files: exportPdf(), exportImage(), exportZip()
const pdf = await editor.exportPdf();
const png = await editor.exportImage({ fullPage: true }); // false: the first screen only
const zip = await editor.exportZip();
Each resolves with the same shape:
{
"url": "https://…/q3-proposal.pdf",
"filename": "q3-proposal.pdf",
"format": "pdf",
"bytes": 48213,
"expiresAt": null,
"warnings": [],
"exportId": "01J9ZR…",
"designId": "01J9ZQ3W8D2K7M5T1V4XG6HB0R",
"revision": 7,
"mode": "document",
"design": { }
}
Fetch the file from url. expiresAt is null while the file is kept; read it rather than
assume it, since how long files are kept may change.
The url is long and unguessable, and works without a key for anyone who has it, as a link to a
file on a CDN does. Hand it only to whoever should have the file, or download the file to your own
storage and share that.
| Format | What is in it |
|---|---|
| A document on its own paper, with header, footer and page numbers. Any other design on A4. | |
| PNG | The design drawn as a picture, the whole length (fullPage: true, the default) or the first screen |
| ZIP | index.html, the plain text, the images Lettrove hosts for it, and a short README. Images hosted elsewhere stay as links. |
All three take merge too.
The design itself: getDesign()
const { designId, revision, design } = await editor.getDesign();
await myDb.saveCopy(designId, design); // keep it as it is
The design is yours to keep. Store it as it is and hand it back to render it on your server
(lettrove.render({ doc: design })) — see Keeping your own copy.
From your server
import { Lettrove } from '@lettrove/node';
const lettrove = new Lettrove({ secretKey: process.env.LETTROVE_SECRET_KEY });
// HTML (and text, chunks, subject…) — the same fields as exportHtml
const email = await lettrove.designs.export(designId, { user: { id: userId }, merge: { contact } });
// A file
const pdf = await lettrove.designs.export(designId, { user: { id: userId }, format: 'pdf' });
const png = await lettrove.designs.export(designId, { user: { id: userId }, format: 'png', fullPage: false });
The server exports the design as last saved; the page exports it as on screen. For the same saved design, both give the same HTML.
In the editor: the Download menu
Your users can download the same files themselves from the Download menu in the editor's bar.
To hide it (because your product handles files), pass features: { download: false }; your code can
still export.