Skip to main content

Configuration

propertyTypeDescription
initialValuesEmailTemplateSource data
heightstringEditor height
onSubmit(values: EmailTemplate, editor: CustomSlateEditor) => void;Called when the commit is triggered manually
onChange(values: EmailTemplate, editor: CustomSlateEditor) => void;Called when the values changed
onUpload(blob: Blob) => Promise<string>Upload image function
fontListArray<{value: string;label: string; href?: string}>Default font list. web font need href
mergetagsMergetagItemA merge tag is a bit of specific code that allows you to insert dynamic data into emails. Like {{user.name}}, and used for preview
mergetagsDataRecord<string, any>;Dynamic data, it will replace mergetags when preview.
newLineWithBrbooleanWhen the user presses enter in the editor, it inserts a new block or a line break (br) by default. The default is true.
categoriesCategoriesConfigure the elements of the left sidebar.
Retro Theme
controllerbooleanZoom in / Zoom out controller
showLayerbooleanShow layer in side bar
showPreviewbooleanShow MJML render preview
showLogicbooleanshow loop/condition configuration
compactbooleansingle side bar / double side bar
unsplash{clientId: string;presetList?: Array<{query: string;label: string;image: string; }> }Unsplash image library

For all configuration options, refer to the EmailEditorProps interface below.

export interface EmailEditorProps {
onUpload?: (blob: Blob) => Promise<string>;
onSubmit: (values: EmailTemplate) => void;
fontList?: {
value: string;
label: string;
}[];
localeData?: Record<string, string>;
initialValues: EmailTemplate;
children: React.ReactNode;
loading?: React.ReactNode;
editor: CustomSlateEditor;
footer?: React.ReactNode;
ElementPlaceholder?: React.FC<{
element: Element;
isSelected: boolean;
isHover: boolean;
nodeElement: HTMLElement;
path: Path;
}>;
ElementHover?: React.FC<{
element: Element;
isSelected: boolean;
nodeElement: HTMLElement;
path: Path;
}>;
ElementSelected?: React.FC<{
element: Element;
isHover: boolean;
nodeElement: HTMLElement;
path: Path;
}>;
MergetagPopover?: React.FC<{
element: MergetagElement;
onSave: (val?: string) => void;
}>;
interactiveStyle?: {
hoverColor?: string;
selectedColor?: string;
dragColor?: string;
};
withEnhanceEditor?: (
editor: CustomSlateEditor,
props: EmailEditorProps
) => CustomSlateEditor;
hoveringToolbar?: {
prefix?: React.ReactNode;
list?: (params: {
isCollapsed?: boolean;
isFocus?: boolean;
selection: BaseSelection;
}) => Array<TextFormat | React.FC>;
subfix?: React.ReactNode;
fixed?: boolean;
follow?: "selection" | "container" | "page";
iconSize?: number;
};
// TextFormat.AI_ASSISTANT needs to be configured in hoveringBar
AIAssistant?: {
onGenerate: (
messages: Array<{ role: string; content: string }>
) => Promise<{ role: string; content: string }>;
};
categories?: Categories;
showSourceCode?: boolean;
universalElementSetting?: {
elements: Record<string, Element>;
list: Array<{
label: string;
elements: Array<{
element: Element;
thumbnail: string;
}>;
}>;
onAddElement: (params: {
name: string;
element: Element;
thumbnail: Blob;
}) => Promise<Element>;
onUpdateElement: (params: {
uid: string;
element: Element;
thumbnail: Blob;
}) => Promise<any>;
};
quantityLimitCheck?: (params: {
element: Element;
pageData: PageElement;
}) => boolean;
controller?: boolean;
showPreview?: boolean;
showSidebar?: boolean;
showLogic?: boolean;
showLayer?: boolean;
compact?: boolean;
height: string;
unsplash?: {
clientId: string;
presetList?: Array<{
query: string;
label: string;
image: string;
}>;
};
}

export interface MergetagItem {
label: string;
value: string;
children?: MergetagItem[];
selectable?: boolean;
type?: "text" | "image" | "link";
}

export interface CategoryGridItem<T extends keyof ElementMap = any> {
label: string;
active?: boolean;
blocks: Array<{
type: Element["type"];
payload?: Partial<ElementMap[T]>;
title?: string | undefined;
icon?: React.ReactNode;
}>;
displayType?: "grid";
}

export type Categories = Array<
| CategoryGridItem
| {
label: string;
active?: boolean;
blocks: Array<{
payload: string[][];
title: string | undefined;
}>;
displayType: "column";
}
| {
label: string;
active?: boolean;
blocks: Array<{
payload?: Partial<Element>;
}>;
displayType: "widget";
}
| {
label: string;
active?: boolean;
blocks: Array<React.ReactNode>;
displayType: "custom";
}
>;