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.