Skip to main content

Configuration

This guide covers all configuration options available in Easy Email Pro. The configuration object is passed to Retro.useCreateConfig() or directly to EmailEditorProvider.

Configuration Overview​

The editor configuration is divided into several categories:

  • Required Properties: Essential options that must be provided
  • Handlers: Callback functions for user actions
  • UI Features: Options to show/hide interface elements
  • Content Configuration: Settings for blocks, fonts, merge tags, etc.
  • Advanced Options: Advanced features and customizations

Required Properties​

PropertyTypeDescriptionDefault
clientIdstringYour Easy Email Pro client ID. Used for authentication and feature authorization.Required
initialValuesEmailTemplateThe initial email template data. This defines the starting state of the editor.Required
heightstringEditor container height. Use CSS values like "100vh", "calc(100vh - 66px)", etc.Required
onSubmit(values: EmailTemplate, editor: CustomSlateEditor) => voidCalled when the user manually triggers save/submit. Use this to save templates to your backend.Required

Example:

const config = Retro.useCreateConfig({
clientId: process.env.CLIENT_ID!, // Your Easy Email Pro client ID
initialValues: {
subject: "Welcome Email",
content: {
/* page element */
},
},
height: "calc(100vh - 66px)",
onSubmit: async (values) => {
await saveTemplate(values);
},
});

Event Handlers​

PropertyTypeDescriptionDefault
onUpload(blob: Blob) => Promise<string>Handles file uploads (images, etc.). Must return the uploaded file URL.Optional
onChange(values: EmailTemplate, editor: CustomSlateEditor) => voidCalled whenever the template is modified. Useful for auto-save, validation, or tracking changes.Optional

Example:

const onUpload = async (file: Blob): Promise<string> => {
const formData = new FormData();
formData.append("file", file);
const response = await fetch("/api/upload", {
method: "POST",
body: formData,
});
const { url } = await response.json();
return url;
};

const onChange = (values: EmailTemplate) => {
// Auto-save, validate, or track changes
console.log("Template changed:", values);
};

UI Features​

These options control which interface elements are visible in the editor.

PropertyTypeDescriptionDefault
showSidebarbooleanShow the left sidebar with block categoriestrue
showLayerbooleanShow the layer tree panel in the sidebarfalse
showPreviewbooleanShow the email preview panel (desktop/mobile tabs)false
showSourceCodebooleanShow the JSON source code panelfalse
showBlockPathsbooleanShow breadcrumb path for the selected block imgfalse
showPreviousLevelIconbooleanShow icon to navigate to parent element imgfalse
showTextHTMLModebooleanAllow HTML editing mode in text blocks imgfalse
showLogicbooleanShow loop/condition configuration panelsfalse
controllerbooleanShow zoom in/out controller imgfalse
compactbooleanUse single sidebar layout instead of double sidebarfalse
showDragMoveIconbooleanShow drag handle icons on blockstrue
showInsertTipsbooleanShow insertion hints when dragging blockstrue
showGenerateBlockImagebooleanShow button to download block screenshots imgfalse

Recommended Configuration:

{
showSidebar: true,
showLayer: true,
showPreview: true,
showSourceCode: true,
compact: false,
}

Content Configuration​

PropertyTypeDescriptionDefault
categoriesCategoriesConfigure block categories and available elements in the sidebar. See Block Categories for details.Default categories
fontListArray<{value: string; label: string; href?: string}>Custom font list. Web fonts require href for @import or link tag.Default fonts
mergetagsMergetagItem[]Merge tag structure for dynamic content. Defines available variables like {{user.name}}.[]
mergetagsDataRecord<string, any>Data object used to preview merge tags. Replaces {{variables}} with actual values.{}

Example - Merge Tags:

const mergetags = [
{
label: "User",
value: "",
children: [
{ label: "Name", value: "user.name" },
{ label: "Email", value: "user.email" },
],
},
];

const mergetagsData = {
user: {
name: "John Doe",
email: "john@example.com",
},
};

Example - Font List:

const fontList = [
{ value: "Arial", label: "Arial" },
{
value: "Roboto",
label: "Roboto",
href: "https://fonts.googleapis.com/css2?family=Roboto",
},
{ value: "Custom Font", label: "Custom", href: "/fonts/custom.css" },
];

Advanced Features​

PropertyTypeDescriptionDefault
clientIdstringClient ID for paid plans. Required for premium features.undefined
instanceRefReact.MutableRefObject<EditorContextProps>Reference to access editor instance programmatically. Useful for custom integrations.undefined
localeDataRecord<string, string>Translation data for localization. See Localization API.{}
sourceCodeEditablebooleanAllow direct editing of JSON source codefalse
emptyPageElementPageElementDefault element shown when canvas is clearedDefault empty page
quantityLimitCheck(params: { element: Element; pageData: PageElement }) => booleanValidation callback when adding blocks. Return false to prevent addition.undefined
universalElementSettingObjectConfiguration for universal (reusable) blocks. See Universal Blocks.undefined
AIAssistantObjectAI assistant configuration. See AI Assistant. imgundefined
unsplash{clientId: string; presetList?: Array}Unsplash integration for image library. Requires Unsplash API client ID. imgundefined

Feature Flags​

These options enable/disable specific editor features:

PropertyTypeDescriptionDefault
enabledGradientImagebooleanEnable gradient background image generation for supported blocks imgfalse
enabledButtonIconbooleanEnable icon configuration for buttons (left/right icons) imgfalse

Block Categories​

The categories property defines which blocks appear in the sidebar and how they're organized.

Example:

const categories: Categories = [
{
label: "Content",
active: true,
displayType: "grid",
blocks: [
{
type: ElementType.STANDARD_TEXT,
icon: <IconFont iconName="icon-text" />,
},
{
type: ElementType.STANDARD_IMAGE,
icon: <IconFont iconName="icon-img" />,
},
],
},
{
label: "Layout",
active: true,
displayType: "column",
blocks: [
{
title: "2 Columns",
payload: [
["50%", "50%"],
["33%", "67%"],
],
},
],
},
];

For more details on configuring categories, see the Examples Section.

Complete Configuration Example​

Here's a complete example showing all configuration options:

import { Retro } from "easy-email-pro-theme";
import { ElementType } from "easy-email-pro-core";

const config = Retro.useCreateConfig({
// Required
initialValues: templateData,
height: "calc(100vh - 66px)",
onSubmit: async (values) => {
await saveTemplate(values);
},

// Handlers
onUpload: async (file) => {
return await uploadToServer(file);
},
onChange: (values) => {
// Handle changes
},

// UI Features
showSidebar: true,
showLayer: true,
showPreview: true,
showSourceCode: true,
showBlockPaths: true,
compact: false,

// Content
categories: [
{
label: "Content",
active: true,
displayType: "grid",
blocks: [
{
type: ElementType.STANDARD_TEXT,
icon: <IconFont iconName="icon-text" />,
},
{
type: ElementType.STANDARD_IMAGE,
icon: <IconFont iconName="icon-img" />,
},
],
},
],
mergetags: [
{
label: "User",
value: "",
children: [{ label: "Name", value: "user.name" }],
},
],
mergetagsData: {
user: { name: "John" },
},

// Advanced
clientId: process.env.CLIENT_ID,
localeData: translationData,
});

Type Definitions​

For complete TypeScript type definitions, refer to the EmailEditorProps interface. All configuration options are fully typed for better development experience.

export interface EmailEditorProps {
// Required properties
initialValues: EmailTemplate;
height: string;
onSubmit: (values: EmailTemplate) => void;

// Optional handlers
onUpload?: (blob: Blob) => Promise<string>;
onChange?: (values: EmailTemplate, editor: CustomSlateEditor) => void;

// ... (see full interface in source code)
}

For the complete interface definition with all properties, check the TypeScript definitions in the easy-email-pro-editor package.

Additional Type Definitions​

Here are some commonly used type definitions for reference:

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";
}
>;