Skip to main content

@lettrove/embed

npm install @lettrove/embed
import { createEditor, LettroveEmbedError } from '@lettrove/embed';

With the script tag (https://cdn.jsdelivr.net/npm/@lettrove/embed@1/dist/lettrove.iife.js) everything below is on the one global, Lettrove: Lettrove.createEditor, Lettrove.LettroveEmbedError…

createEditor(options)​

Opens the editor in options.container and resolves with an EditorHandle once it is on screen. Rejects with a LettroveEmbedError when it cannot open.

async function getToken() {
const response = await fetch('/lettrove-token', { method: 'POST' });
return (await response.json()).token;
}

const editor = await createEditor({
container: '#editor',
publishableKey: 'lt_pk_test_…',
getToken,
});

Options​

OptionTypeDefault
containerHTMLElement | stringrequiredThe element the editor fills, or a CSS selector. Give it a height.
publishableKeystringrequiredlt_pk_test_… or lt_pk_live_…. A secret key here is refused.
getToken() => Promise<string>requiredResolves with a fresh token string from your server. Called when the editor opens and before each token expires.
designIdstring | nullnew designThe design to open.
releasestringthis package's line ('1')The editor release: '1', '1.2', '1.2.3', 'stable'. Releases
signalAbortSignal—Aborting removes the editor; createEditor then rejects with editor_destroyed.
on{ [event]: listener }—Listeners attached before the editor opens.
mode'email' | 'page' | 'popup' | 'document'the project'sA check: a different mode than the project's is refused (mode_unavailable).
tabs{ blocks?, layers?, brand?, inspector?, images?, history?: boolean }all onfalse removes a panel.
tools.disabledToolName[][]Tools the palette does not offer.
tools.orderToolName[]default orderThe palette's order; tools left out follow.
features.undoRedobooleantrueUndo and redo.
features.preview.mobilebooleantrueThe phone preview.
features.ai.imagesbooleanthe project'sPicture generation.
features.themeSwitchbooleantrueThe editor's own light / dark switch.
features.downloadbooleantrueThe Download menu.
branding.poweredBybooleanfalseAdds "Powered by Lettrove". Your name and logo are set in the dashboard.
appearance.theme'light' | 'dark' | 'auto''auto'
appearance.variablesThemeTokens—The light theme's tokens.
appearance.darkVariablesThemeTokens—The dark theme's tokens.
appearance.panels.palette.dock'left' | 'right''left'
appearance.panels.inspector.dock'left' | 'right''right'
storage.images'lettrove' | 'host''lettrove''host': your providers store your users' uploads. Your own upload handler
providers['image:upload'](file, { signal }) => Promise<HostedImage | ProviderFailure>—Required with storage.images: 'host'.
providers['image:list']({ query, cursor, limit }, { signal }) => Promise<{ items, nextCursor } | ProviderFailure>—Your library, for the Images panel.
storage.designs'lettrove' | 'host''lettrove''host': your providers keep your users' designs, in your database. Your own design storage
providers['design:load']({ id }, { signal }) => Promise<{ design, revision } | ProviderFailure>—Required with storage.designs: 'host'.
providers['design:save']({ id, design, revision, idempotencyKey }, { signal }) => Promise<{ id, revision, savedAt } | { conflict: { theirs, revision } } | ProviderFailure>—Required with storage.designs: 'host'.

ToolName is one of section, text, heading, image, button, divider, spacer, social, html, form. Options can only narrow what the project allows: Options.

ThemeTokens​

All optional strings: accent, accentText, surface, surfaceRaised, text, textMuted, border, focusRing, radius, fontFamily. What each colours: Theming.

EditorHandle​

Member
design: { designId, revision }The design that is open.
release: stringThe editor release running, e.g. '1.0.0'.
on(event, listener): () => voidListen for an event; call the returned function to stop.
setTheme(theme): Promise<'light' | 'dark'>Switch theme while open; resolves with what it shows.
exportHtml(options?): Promise<ExportResult>The design as on screen, as HTML (and chunks, text, subject…).
exportPlainText(options?): Promise<PlainTextResult>As plain text.
exportImage(options?): Promise<FileResult>As a PNG (fullPage, default true).
exportPdf(options?): Promise<FileResult>As a PDF.
exportZip(options?): Promise<FileResult>As a ZIP.
getDesign(): Promise<DesignSnapshot>The design document: { designId, revision, design }.
destroy(): voidRemoves the editor and everything it set up. Safe to call twice.

After destroy, every method rejects with editor_destroyed. Options and results of each export: Getting designs out.

ExportResult​

exportId, designId, revision, mode, html, chunks ({ body, css, js, fonts }), text, subject, preheader, mergeTags, rendererVersion, bytes, warnings, design.

FileResult​

exportId, designId, revision, mode, format ('png' | 'pdf' | 'zip'), url, expiresAt (string | null), filename, bytes, warnings, design.

HostedImage​

What an image provider answers: url (required, absolute https://), and optionally width, height, alt, mime, bytes, id (your own id, kept on the image in the design). ProviderFailure is { error: { message, code? } }.

MergeValues​

{ contact?: Record<string, string>; unsubscribeUrl?: string; preferencesUrl?: string } — the merge option of every export. Merge tags

Events​

ready, design:loaded, design:updated, design:saved, selection:changed, image:uploaded, theme:changed, config:adjusted, error. Every payload: Events.

LettroveEmbedError​

try {
await createEditor({ /* … */ });
} catch (e) {
if (e instanceof LettroveEmbedError) console.error(e.code, e.message); // e.g. 'frame_blocked'
}

code is one of the error codes; message says what to fix; docsUrl links to that code's row on the error page, for your logs.

Other exports​

Export
LOADER_VERSIONThis package's version, e.g. '1.0.0'.
DEFAULT_RELEASEThe release opened when you pass none ('1' for a 1.x package).
DEFAULT_EMBED_ORIGIN'https://lettrove-embed.com'.
TypesCreateEditorOptions, EditorOptions, EditorHandle, EditorEvents, EventName, ErrorCode, ExportOptions, ExportResult, PlainTextOptions, PlainTextResult, ImageOptions, FileExportOptions, FileResult, HtmlChunks, MergeValues, TextOptions, DesignRef, DesignSnapshot, DesignDocument, Mode, TabName, Theme, ThemeTokens, ToolName, Dock, Providers, ProviderContext, ProviderFailure, HostedImage