mcpField
U
unlayer-integration

unlayer-integration

github.com/unlayer開発14129 回インストール3 週間前に更新
リポジトリ

unlayer-integration について

React、Vue、Angular、またはプレーン JavaScript のアプリに Unlayer エディターを組み込むための開発スキルです。フレームワーク別のアクセス方法、初期設定、複数インスタンスの扱いを説明します。

主な機能

  1. 01React、Vue、Angular 用ラッパー
  2. 02プレーン JavaScript での組み込み
  3. 03フレームワーク別のエディターアクセス
  4. 04デザインの保存と読み込みパターン
  5. 05createEditor() による複数インスタンス

活用シーン

  1. 01Web アプリへのメールビルダー組み込み
  2. 02編集可能なデザインの読み込みと保存
  3. 03メール用と Web 用のエディターを別々に実行

インストール

コマンドをコピーしてターミナルで実行します。

$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   # 最新の公開バージョンを確認

確認していないバージョン番号を指定しないでください。最新バージョンを取得するには、バージョンを指定せずに 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 の Props:

Prop型デフォルト説明
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>

Props: 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


複数のエディターインスタンス

init() の代わりに createEditor() を使用します。

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 が undefined になるマウント前にアクセスしていますonReady コールバック内でのみ使用します
デザインが読み込まれないJSON の形式が不正ですJSON を検証し、schemaVersion フィールドを確認します

リソース

コメント