Skip to content

Props ​

All optional.

PropTypeDescription
designEmailDocumentThe document's design (v-model:design). Without it, the editor starts blank.
mergeTagsMergeTagItem[]Variables insertable in text: { name, value }, or groups { name, tags: MergeTagDef[] } (shown as optgroups).
templatesEmailTemplate[]Extra templates, in addition to the built-in defaults.
uploadImage(file: File) => Promise<string>Upload handler; returns the final URL. Without this prop, the Image block can't upload new files.
imageSearch(query: string) => Promise<ImageResult[]>Search handler for the Search subtab in the unified Images panel; defaults to openverseSearch (Openverse, CC0/CC-BY).
mediaLibraryMediaLibraryOptionsEnables the Gallery subtab in the unified Images panel: { list: (cursor?) => Promise<{ items: MediaItem[], nextCursor? }>, upload: (file) => Promise<MediaItem>, delete: (id) => Promise<void>, rename: (id, name) => Promise<MediaItem> }. Without this prop, only Search is shown. You implement each function against your own storage — the library assumes no particular backend.
timerImageUrlBuilder(block: TimerBlock) => string | undefinedOptional email-safe timer image provider. Called during live preview and HTML export when the timer has no explicit imageUrl; return a remotely served GIF or generated image URL. Without it, exported timers are static snapshots because email clients cannot run a live countdown.
socialIconUrlBuilder(kind: SocialNetworkKind) => string | undefinedOptional provider for hosted email social icon URLs. Defaults to HTTPS icon URLs; return self-hosted assets for production control. Empty or throwing callbacks use the default URL.
unlayerFetch(slug: string) => Promise<unknown>Handler to load an Unlayer template by URL/slug; returns the design JSON. Defaults to hitting Unlayer's public API (fails via CORS without your own proxy).
theme'light' | 'dark'Builder UI theme (doesn't affect the email canvas).
showHeaderbooleanWhether to show the builder header. Defaults to true; when false, the entire builder header is hidden.
locale'en' | 'es' | LocaleDictPublic UI language option. English ('en') is the default, Spanish ('es') is the built-in alternative, and a LocaleDict is merged on top of English so you can override only the keys you want.
appearanceAppearance | ThemeAppearanceBuilder colors. A flat object ({ accent, panel, border, background, foreground, muted }) applies to both modes. The union Appearance or ThemeAppearance also accepts { light?: Appearance, dark?: Appearance } for mode-specific values; omitted fields keep that mode's defaults.
aiAiOptionsOptional Chrome built-in AI tools for the rich text editor: { enabled: boolean, languages?: AiLanguage[] }. The menu is rendered only when enabled; languages configures Translate targets. Browser API availability is checked at runtime.
aiTemplatesAiTemplateOptionsOptional provider-agnostic AI template generation: { enabled, context?, generate }. The user explicitly chooses create/edit mode and 1–3 proposals; the callback is owned by your application. See AI template generation.
autosaveAutosaveOptionsOptional autosave config: { enabled, storage, mode?, delay?, restore?, restorePrecedence? }. Supports local browser storage or your own custom adapter. See Autosave.
toolsPartial<Record<BlockType, ToolConfig>>Per-block palette config: { enabled?, position?, usageLimit? } to hide, reorder, or limit instances of a block type.
fontsFontDef[]List of available fonts ({ label, value, url? }); the ones with url (Google Fonts) are loaded both in the canvas and in the exported HTML. Defaults to a curated list.
specialLinksSpecialLink[]Predefined links insertable from the text editor ({ name, href }) — for example, an unsubscribe link resolved by your sending platform.
customBlocksCustomBlockDef[]Integrator-defined custom blocks — see Custom blocks.

Locale ​

English is the default builder language:

vue
<EmailBuilder locale="en" />
<EmailBuilder locale="es" />

You can also pass a partial dictionary to customize just a few labels while keeping English for every missing key:

vue
<script setup lang="ts">
import { EmailBuilder, type LocaleDict } from '@naturaldevcr/vue-mail-designer'

const partialLocale: LocaleDict = {
  'images.gallery': 'Brand library',
  'image.searchPlaceholder': 'Search product photos',
}
</script>

<template>
  <EmailBuilder :locale="partialLocale" />
</template>

Images panel ​

The builder has one Images panel with two subtabs:

  • Gallery shows your uploaded assets from mediaLibrary and is the first, default subtab when configured.
  • Search shows results from imageSearch (or openverseSearch if you do not provide one). Without mediaLibrary, Search is the only subtab.

Clicking a thumbnail opens a preview dialog first. Select Add to insert a new Image block or replace the currently selected Image block. You can also drag thumbnails straight from Search or Gallery onto the canvas, onto an existing Image block, or onto a Gallery block slot.

See also Events and Methods.

Export tab ​

The right rail's Export tab contains the native HTML, JSON, JSON import, Unlayer import, PNG, and version actions. The same document operations are available programmatically through the component ref; see Methods.

Chrome AI ​

See Chrome AI tools for the complete configuration, action behavior, browser-availability notes, and Apply/Discard flow.

AI template generation ​

See AI template generation for the provider callback, dynamic context, proposal validation, preview/apply flow, errors, and API-key guidance.

Autosave ​

autosave is fully optional. When enabled, the builder persists the current EmailDocument through one of these public storage shapes:

ts
type AutosaveStorage =
  | {
      type: 'local'
      key: string
      storage?: Storage
    }
  | {
      type: 'custom'
      load?: () => Promise<EmailDocument | undefined> | EmailDocument | undefined
      save: (document: EmailDocument) => Promise<void> | void
    }

AutosaveOptions is:

ts
type AutosaveOptions = {
  enabled: boolean
  storage: AutosaveStorage
  mode?: 'change' | 'debounce' | 'interval'
  delay?: number
  restore?: boolean
  restorePrecedence?: 'initial-design' | 'saved-design'
}
  • restore defaults to false (off), so a saved draft does not replace the initial design unless restoration is enabled
  • mode defaults to 'debounce'
  • delay defaults to 1000 for 'debounce', 5000 for 'interval', and 0 for 'change'
  • restorePrecedence defaults to 'initial-design'
  • save-only custom adapters are supported because load is optional

See Autosave for local-storage usage, restore rules, events, cleanup, and host-owned remote data behavior.

For example, use the per-mode form to configure a dark builder with distinct light and dark palettes:

vue
<EmailBuilder
  :show-header="false"
  theme="dark"
  :appearance="{
    light: { accent: '#2563eb', panel: '#ffffff' },
    dark: { accent: '#60a5fa', panel: '#111827' },
  }"
/>

Released under the MIT License. llms.txt for AI assistants.