mcpField
U
unlayer-integration

unlayer-integration

github.com/unlayer开发14129 次安装4 周前更新
代码仓库

关于 unlayer-integration

用于在 React、Vue、Angular 或纯 JavaScript 应用中嵌入 Unlayer 编辑器的开发技能,介绍各框架的访问方式、编辑器配置及多实例处理。

主要功能

  1. 01React、Vue 和 Angular 封装
  2. 02纯 JavaScript 嵌入方式
  3. 03各框架对应的编辑器访问方式
  4. 04设计的保存与加载模式
  5. 05使用 createEditor() 创建多个实例

适用场景

  1. 01在 Web 应用中嵌入邮件构建器
  2. 02加载并保存可编辑设计
  3. 03分别运行邮件和网页编辑器实例

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/unlayer/unlayer-skills --skill unlayer-integration

安装后在 Claude Code 中输入/unlayer-integration确认已加载。

详细介绍

集成 Unlayer Editor

概述

Unlayer 提供 React、Vue 和 Angular 的官方包装组件,以及纯 JavaScript 嵌入方式。所有包装组件都共用相同的底层 API,只有编辑器的访问方式不同。

此技能涵盖邮件、页面、弹窗和文档构建器。对于独立的 Image Editor 或 @unlayer/react-image-editor,请使用 unlayer-image-editor。

选择哪个框架?

框架包安装编辑器访问方式
Reactreact-email-editornpm i react-email-editoruseRef<EditorRef> → ref.current?.editor
Vuevue-email-editornpm i vue-email-editorthis.$refs.emailEditor.editor
Angularangular-email-editornpm i angular-email-editor@ViewChild → this.emailEditor.editor
纯 JSCDN 脚本标签<script> 嵌入全局 unlayer 对象

⚠️ 安装任何 Unlayer 包之前,请先确认该版本已发布到 npm:

npm view react-email-editor version   # check latest published version

切勿固定使用未经确认的版本号。使用 npm install <package> --save(不指定版本)以获取最新版本,或运行 npm view <package> versions --json 查看所有可用版本。


React(完整可运行示例)

npm install react-email-editor --save
import React, { useRef, useState } from 'react';
import EmailEditor, { EditorRef, EmailEditorProps } from 'react-email-editor';

const EmailBuilder = () => {
  const emailEditorRef = useRef<EditorRef>(null);
  const [saving, setSaving] = useState(false);

  // Save design JSON + export HTML to your backend
  const handleSave = () => {
    const unlayer = emailEditorRef.current?.editor;
    if (!unlayer) return;

    setSaving(true);
    unlayer.exportHtml(async (data) => {
      try {
        const response = await fetch('/api/templates', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            design: data.design,  // Save this — needed to edit later
            html: data.html,      // The rendered HTML output
          }),
        });
        if (!response.ok) throw new Error('Save failed');
        console.log('Saved successfully');
      } catch (err) {
        console.error('Save error:', err);
      } finally {
        setSaving(false);
      }
    });
  };

  // Load a saved design when editor is ready
  const onReady: EmailEditorProps['onReady'] = async (unlayer) => {
    try {
      const response = await fetch('/api/templates/123');
      if (response.ok) {
        const saved = await response.json();
        unlayer.loadDesign(saved.design); // Pass the saved design JSON
      }
    } catch (err) {
      console.log('No saved design, starting blank');
    }
  };

  return (
    <div>
      <button onClick={handleSave} disabled={saving}>
        {saving ? 'Saving...' : 'Save'}
      </button>
      <EmailEditor
        ref={emailEditorRef}
        onReady={onReady}
        options={{
          projectId: 123456, // Dashboard > Project > Settings
          displayMode: 'email',
        }}
      />
    </div>
  );
};

export default EmailBuilder;

后端应接受并返回:

// POST /api/templates — save
{ design: object, html: string }

// GET /api/templates/:id — load
{ design: object, html: string, updatedAt: string }

React 属性:

属性类型默认值说明
optionsObject{}所有 unlayer.init() 选项(projectId、displayMode 等)
toolsObject{}每个工具的配置
appearanceObject{}主题和面板设置
onReadyFunction—编辑器就绪时调用(接收 unlayer 实例)
onLoadFunction—iframe 加载时调用(就绪前)
styleObject{}容器内联样式
minHeightString'500px'编辑器最小高度

文档:https://docs.unlayer.com/builder/react-component GitHub:https://github.com/unlayer/react-email-editor


Vue(完整可运行示例)

npm install vue-email-editor --save
<template>
  <div id="app">
    <button v-on:click="handleSave" :disabled="saving">
      {{ saving ? 'Saving...' : 'Save' }}
    </button>
    <EmailEditor ref="emailEditor" v-on:load="editorLoaded" />
  </div>
</template>

<script>
import { EmailEditor } from 'vue-email-editor';

export default {
  components: { EmailEditor },
  data() {
    return { saving: false };
  },
  methods: {
    async editorLoaded() {
      try {
        const response = await fetch('/api/templates/123');
        if (response.ok) {
          const saved = await response.json();
          this.$refs.emailEditor.editor.loadDesign(saved.design);
        }
      } catch (err) {
        console.log('No saved design, starting blank');
      }
    },
    handleSave() {
      this.saving = true;
      this.$refs.emailEditor.editor.exportHtml(async (data) => {
        try {
          await fetch('/api/templates', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ design: data.design, html: data.html }),
          });
        } catch (err) {
          console.error('Save error:', err);
        } finally {
          this.saving = false;
        }
      });
    },
  },
};
</script>

属性: minHeight、options、tools、appearance、locale、projectId。

文档:https://docs.unlayer.com/builder/vue-component GitHub:https://github.com/unlayer/vue-email-editor


Angular(完整可运行示例)

npm install angular-email-editor --save

模块(app.module.ts):

import { EmailEditorModule } from 'angular-email-editor';

@NgModule({ imports: [EmailEditorModule] })
export class AppModule {}

组件(app.component.ts):

import { Component, ViewChild } from '@angular/core';
import { EmailEditorComponent } from 'angular-email-editor';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  @ViewChild(EmailEditorComponent)
  private emailEditor: EmailEditorComponent;
  saving = false;

  async editorLoaded() {
    try {
      const response = await fetch('/api/templates/123');
      if (response.ok) {
        const saved = await response.json();
        this.emailEditor.editor.loadDesign(saved.design);
      }
    } catch (err) {
      console.log('No saved design');
    }
  }

  handleSave() {
    this.saving = true;
    this.emailEditor.editor.exportHtml(async (data) => {
      try {
        await fetch('/api/templates', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ design: data.design, html: data.html }),
        });
      } catch (err) {
        console.error('Save error:', err);
      } finally {
        this.saving = false;
      }
    });
  }
}

模板(app.component.html):

<div>
  <button (click)="handleSave()" [disabled]="saving">
    {{ saving ? 'Saving...' : 'Save' }}
  </button>
  <email-editor (loaded)="editorLoaded($event)"></email-editor>
</div>

文档:https://docs.unlayer.com/builder/angular-component


纯 JavaScript

<script src="https://editor.unlayer.com/embed.js"></script>
<div id="editor-container" style="height: 700px;"></div>

<script>
  unlayer.init({
    id: 'editor-container',
    projectId: 1234,
    displayMode: 'email',
  });

  unlayer.addEventListener('editor:ready', async function () {
    try {
      const response = await fetch('/api/templates/123');
      if (response.ok) {
        const saved = await response.json();
        unlayer.loadDesign(saved.design);
      }
    } catch (err) {
      console.log('Starting blank');
    }
  });

  function handleSave() {
    unlayer.exportHtml(async function (data) {
      await fetch('/api/templates', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ design: data.design, html: data.html }),
      });
    });
  }
</script>

文档:https://docs.unlayer.com/builder/installation


多个编辑器实例

使用 createEditor() 而不是 init():

const editor1 = unlayer.createEditor({ id: 'email-editor', displayMode: 'email' });
const editor2 = unlayer.createEditor({ id: 'web-editor', displayMode: 'web' });

editor1.loadDesign(emailDesign);
editor2.loadDesign(webDesign);

常见错误

错误修正方法
容器过小最小尺寸为 1024px 宽 x 700px 高。编辑器会填满容器。
就绪前调用方法始终等待 editor:ready 事件或 onReady 回调
多个编辑器使用 init()改用 unlayer.createEditor()
缺少 projectId从 Dashboard > Project > Settings 获取
只保存 HTML,不保存设计 JSON始终同时保存两者——设计 JSON 可让用户之后继续编辑
保存时没有加载状态禁用保存按钮,防止重复保存
固定使用不存在的包版本固定版本前运行 npm view <package> version 确认。使用 npm install <package> --save(不指定版本)以获取最新版本。

故障排除

错误原因修复方法
编辑器显示空白容器 div 的高度为 0设置明确的高度:min-height: 700px
editor:ready 从未触发脚本未加载或 id 错误检查 id 是否与现有的 div 匹配,并检查网络选项卡中的 embed.js
ref.current?.editor 未定义在挂载前访问仅在 onReady 回调中使用
设计未加载JSON 格式错误验证 JSON,并检查 schemaVersion 字段

资源

评论

支持 Markdown