Skip to content

Editor API

The main entry point is the init() function from @templatical/vue.

init(config)

Creates and mounts the editor into a container element.

ts
import { init } from '@templatical/vue';
import '@templatical/vue/style.css';

const editor = init({
  container: '#editor',
  content: savedTemplate,
  onChange(content) {
    // Auto-save or update state
  },
});

Returns: TemplaticalEditor

unmount()

Destroys the editor instance and cleans up event listeners.

ts
import { unmount } from '@templatical/vue';

unmount();

TemplaticalEditorConfig

PropertyTypeRequiredDescription
containerstring | HTMLElementYesCSS selector or DOM element to mount the editor into
contentTemplateContentNoInitial template content. Defaults to empty template
onChange(content: TemplateContent) => voidNoCalled when template content changes (debounced)
onSave(content: TemplateContent) => voidNoCalled when the user triggers a save action
onError(error: Error) => voidNoCalled when an error occurs
onRequestMedia(callback: (url: string) => void) => voidNoCalled when user wants to pick an image. Call callback with the URL
onRequestMergeTag() => Promise<MergeTag | null>NoCalled when user wants to insert a merge tag. Return the tag or null
mergeTagsMergeTagsConfigNoMerge tag configuration. See Merge Tags
displayConditionsDisplayConditionsConfigNoDisplay condition configuration. See Display Conditions
customBlocksCustomBlockDefinition[]NoCustom block type definitions. See Custom Blocks
fontsFontsConfigNoFont configuration. See Theming
themeThemeOverridesNoColor token overrides. See Theming
localestringNoLocale code (e.g. 'en', 'de'). Defaults to 'en'
darkModeboolean | 'auto'NoDark mode setting. 'auto' follows system preference
pluginsEditorPlugin[]NoEditor plugins. See Plugin System

TemplaticalEditor

The object returned by init().

getContent()

Returns the current template content as a TemplateContent object.

ts
const content = editor.getContent();
// { blocks: [...], settings: { width: 600, ... } }

setContent(content)

Replaces the editor content.

ts
import { createDefaultTemplateContent } from '@templatical/types';

editor.setContent(createDefaultTemplateContent());

unmount()

Destroys this editor instance.

toMjml()

Renders the current content to MJML markup. Only available when @templatical/renderer is installed.

ts
const mjml = editor.toMjml?.();

toHtml()

Renders the current content to HTML. Only available when @templatical/renderer is installed. Returns a Promise because MJML compilation is async.

ts
const html = await editor.toHtml?.();

Plugin System

Plugins extend the editor with custom toolbar actions, sidebar panels, and block context actions.

EditorPlugin

ts
interface EditorPlugin {
  name: string;
  install(context: EditorPluginContext): void | Promise<void>;
  destroy?(): void;
}

EditorPluginContext

The context passed to install():

PropertyTypeDescription
stateDeepReadonly<EditorState>Current editor state
contentRef<TemplateContent>Reactive template content
selectedBlockIdRef<string | null>Currently selected block ID
viewportRef<ViewportSize>Current viewport
addBlock(block, sectionId?, colIdx?, idx?) => voidAdd a block
updateBlock(blockId, updates) => voidUpdate a block
removeBlock(blockId) => voidRemove a block
moveBlock(blockId, newIdx, sectionId?, colIdx?) => voidMove a block
updateSettings(updates) => voidUpdate template settings
selectBlock(blockId | null) => voidSelect a block
registerToolbarAction(action: ToolbarAction) => voidAdd a toolbar button
registerSidebarPanel(panel: SidebarPanel) => voidAdd a sidebar panel
registerBlockAction(action: BlockContextAction) => voidAdd a block context menu action

Example Plugin

ts
const analyticsPlugin: EditorPlugin = {
  name: 'analytics',
  install(ctx) {
    ctx.registerToolbarAction({
      id: 'analytics',
      icon: 'bar-chart',
      label: 'Analytics',
      onClick() {
        const blockCount = ctx.content.value.blocks.length;
        console.log(`Template has ${blockCount} blocks`);
      },
    });
  },
};

const editor = init({
  container: '#editor',
  plugins: [analyticsPlugin],
});

Core Composables

For advanced use cases, you can use the composables from @templatical/core directly.

useEditor(options)

Manages editor state, block selection, viewport, and content mutations.

ts
import { useEditor } from '@templatical/core';

const editor = useEditor({ content: templateContent });

editor.selectBlock(blockId);
editor.updateBlock(blockId, { content: 'New text' });
editor.setViewport('mobile');

useHistory(options)

Provides undo/redo functionality.

ts
import { useHistory } from '@templatical/core';

const history = useHistory({
  content: editor.content,
  setContent: editor.setContent,
  maxSize: 50,
});

history.undo();
history.redo();

useBlockActions(options)

High-level block creation, duplication, and deletion.

ts
import { useBlockActions } from '@templatical/core';

const actions = useBlockActions({
  addBlock: editor.addBlock,
  removeBlock: editor.removeBlock,
  updateBlock: editor.updateBlock,
  selectBlock: editor.selectBlock,
});

const newBlock = actions.createAndAddBlock('text');
actions.duplicateBlock(existingBlock);
actions.deleteBlock(blockId);

useAutoSave(options)

Debounced auto-save with pause/resume control.

ts
import { useAutoSave } from '@templatical/core';

const autoSave = useAutoSave({
  content: editor.content,
  isDirty: editor.state.isDirty,
  onChange: (content) => saveToServer(content),
  debounce: 1000,
});

autoSave.flush();   // Save immediately
autoSave.pause();   // Pause auto-save
autoSave.resume();  // Resume