mcpField
U
unlayer-config

unlayer-config

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

unlayer-config について

Unlayer エディターを組み込む開発者向けの設定スキルです。エディターのオプションや実行時メソッドを扱い、外観、動的コンテンツ、アップロード、セキュリティ、ローカライズ、検証を説明します。

主な機能

  1. 01エディター機能とタブの設定
  2. 02テーマとカスタムフォントの設定
  3. 03マージタグとデザインタグの追加
  4. 04独自画像アップロードの接続
  5. 05サーバー側 HMAC 署名の生成
  6. 06ローカライズと検証の設定

活用シーン

  1. 01埋め込みメールエディターのカスタマイズ
  2. 02テンプレートに個別のプレースホルダーを表示
  3. 03ユーザー画像をバックエンドに保存
  4. 04エディターの内容を検証・サニタイズ

インストール

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

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

インストール後、Claude Code で/unlayer-configを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
feature-flags.md
file-storage.md
security.md

詳細

エディターを設定する

概要

Unlayer の動作は、unlayer.init() のオプションと実行時メソッドによって制御されます。このスキルでは、機能、外観、動的コンテンツ、セキュリティ、ファイルストレージについて説明します。

ビルダー内の画像から開く画像エディターも対象です。スタンドアロンの Image Editor および @unlayer/react-image-editor については、unlayer-image-editor を使用してください。

キーの確認場所:

  • Project ID — Dashboard > Project > Settings
  • Project Secret(HMAC 用)— Dashboard > Project > Settings > API Keys
  • Cloud API Key(画像/PDF のエクスポート用)— Dashboard > Project > Settings > API Keys

Dashboard:console.unlayer.com


機能フラグ

エディターで利用できる機能を制御します:

unlayer.init({
  features: {
    audit: true,             // Content validation
    preview: true,           // Preview button
    undoRedo: true,          // Undo/redo
    stockImages: true,       // Stock photo library
    userUploads: true,       // User upload tab
    preheaderText: true,     // Email preheader field
    textEditor: {
      spellChecker: true,
      tables: false,         // Tables inside text blocks
      cleanPaste: 'confirm', // true | false | 'basic' | 'confirm'
      emojis: true,
    },

    // Paid features:
    ai: true,                // AI text generation
    collaboration: false,    // Real-time collaboration
    sendTestEmail: false,    // Test email button
  },
});

すべてのフラグ(AI のサブオプション、画像エディター、カラーピッカーなど)については、references/feature-flags.md を参照してください。


外観とテーマ設定

unlayer.init({
  appearance: {
    theme: 'modern_dark',    // 'modern_light' | 'modern_dark' | 'classic_light' | 'classic_dark'
    panels: {
      tools: {
        dock: 'right',       // 'left' | 'right' (default: 'right')
        collapsible: true,
      },
    },
    actionBar: {
      placement: 'top',     // 'top' | 'bottom' | 'top_left' | 'top_right' | 'bottom_left' | 'bottom_right'
    },
  },
});

// Change at runtime:
unlayer.setAppearance({ theme: 'modern_dark' });
// Or just the theme:
unlayer.setTheme('modern_dark');
カスタムフォント
unlayer.init({
  fonts: {
    showDefaultFonts: true,
    customFonts: [{
      label: 'Poppins',
      value: "'Poppins', sans-serif",
      url: 'https://fonts.googleapis.com/css?family=Poppins:400,700',
      weights: [400, 700],  // or [{ label: 'Regular', value: 400 }, { label: 'Bold', value: 700 }]
    }],
  },
});
タブ設定
unlayer.init({
  tabs: {
    content: { enabled: true, position: 1 },
    blocks: { enabled: true, position: 2 },
    body: { enabled: true, position: 3 },
    images: { enabled: true, position: 4 },
    uploads: { enabled: true, position: 5 },
  },
});

マージタグ

マージタグは、送信時に置き換えられるプレースホルダーです(例:{{first_name}})。テンプレートエンジンの構文(Handlebars、Liquid、Jinja など)を使用します:

unlayer.setMergeTags({
  first_name: {
    name: 'First Name',
    value: '{{first_name}}',        // Your template syntax
    sample: 'John',                  // Shown in editor preview
  },
  last_name: {
    name: 'Last Name',
    value: '{{last_name}}',
    sample: 'Doe',
  },
  company: {
    name: 'Company',                 // Nested group
    mergeTags: {
      name: { name: 'Company Name', value: '{{company.name}}', sample: 'Acme Inc' },
      logo: { name: 'Logo URL', value: '{{company.logo}}' },
    },
  },
  products: {
    name: 'Products',
    rules: {
      repeat: {
        name: 'Repeat for Each Product',
        before: '{{#each products}}', // Loop start — syntax depends on your template engine
        after: '{{/each}}',           // Loop end
        sample: true,                  // Show sample data in editor
      },
    },
    mergeTags: {
      name: { name: 'Product Name', value: '{{this.name}}' },
      price: { name: 'Price', value: '{{this.price}}' },
      image: { name: 'Image URL', value: '{{this.image}}' },
    },
  },
});

// Autocomplete trigger (optional)
unlayer.setMergeTagsConfig({ autocompleteTriggerChar: '{{', sort: true });
デザインタグ(エディター専用のプレースホルダー)

デザインタグはエディター UI 内で置き換えられますが、エクスポート時には置き換えられません。テンプレート作成者にパーソナライズされたコンテンツを表示する場合に便利です:

unlayer.setDesignTags({
  business_name: 'Acme Corp',
  current_user_name: 'Jane Smith',
});
unlayer.setDesignTagsConfig({ delimiter: ['{{', '}}'] });
表示条件(有料)

テンプレートエンジン用の条件ブロックでコンテンツを囲みます:

unlayer.setDisplayConditions([
  {
    type: 'segment',
    label: 'VIP Customers',
    description: 'Only shown to VIP segment',
    before: '{% if customer.vip %}',   // Your template engine syntax
    after: '{% endif %}',
  },
  {
    type: 'segment',
    label: 'New Subscribers',
    description: 'First 30 days only',
    before: '{% if subscriber.age_days < 30 %}',
    after: '{% endif %}',
  },
]);
特殊リンク

ユーザーが挿入できる事前定義済みのリンク(配信停止、設定など):

unlayer.setSpecialLinks({
  unsubscribe: {
    name: 'Unsubscribe',
    href: '{{unsubscribe_url}}',
    target: '_blank',
  },
  preferences: {
    name: 'Preferences',
    specialLinks: {
      email_prefs: { name: 'Email Preferences', href: '{{preferences_url}}' },
      profile: { name: 'Profile Settings', href: '{{profile_url}}' },
    },
  },
});

HMAC セキュリティ

ユーザーが互いになりすますのを防ぎます。Project Secret(Dashboard > Project > Settings > API Keys)を使用して、HMAC 署名をサーバー側で生成します:

Node.js:

const crypto = require('crypto');
const signature = crypto
  .createHmac('sha256', 'YOUR_PROJECT_SECRET')  // From Dashboard
  .update(String(userId))
  .digest('hex');

Python/Django:

import hmac, hashlib

signature = hmac.new(
    b'YOUR_PROJECT_SECRET',
    bytes(str(request.user.id), encoding='utf-8'),
    digestmod=hashlib.sha256
).hexdigest()

クライアント側 — サーバーで生成した署名を渡します:

unlayer.init({
  user: {
    id: userId,                       // Must match what you signed
    signature: signatureFromServer,    // HMAC from your backend
    name: 'John Doe',                 // Optional
    email: '[email protected]',          // Optional
  },
});

Ruby と PHP の例については、references/security.md を参照してください。


ファイルストレージと画像のアップロード

カスタムアップロード(自分のサーバー)
unlayer.registerCallback('image', (file, done) => {
  const data = new FormData();
  data.append('file', file.attachments[0]);

  fetch('/api/uploads', { method: 'POST', body: data })
    .then((r) => {
      if (!r.ok) throw new Error('Upload failed');
      return r.json();
    })
    .then((result) => done({ progress: 100, url: result.url }))
    .catch((err) => console.error('Upload error:', err));
});

バックエンドから次の形式で返します:

{ "url": "https://your-cdn.com/images/uploaded-file.png" }
ファイルマネージャー(アップロード済み画像の参照)

init に user.id が必要です。画像はユーザーごとに管理されます:

unlayer.init({
  user: { id: 123 },                  // Required for file manager
  features: { userUploads: { enabled: true, search: true } },
});

unlayer.registerProvider('userUploads', (params, done) => {
  // params: { page, perPage, searchText }
  fetch(`/api/images?userId=123&page=${params.page}&perPage=${params.perPage}`)
    .then((r) => r.json())
    .then((data) => {
      done(
        data.items.map((img) => ({
          id: img.id,                  // Required
          location: img.url,           // Required — the image URL
          width: img.width,            // Optional but recommended
          height: img.height,          // Optional but recommended
          contentType: img.contentType, // Optional: 'image/png'
          source: 'user',              // Required: must be 'user'
        })),
        { hasMore: data.hasMore, page: params.page, total: data.total }
      );
    });
});

バックエンドから次の形式で返します:

{
  "items": [
    { "id": "img_1", "url": "https://...", "width": 800, "height": 600, "contentType": "image/png" }
  ],
  "hasMore": true,
  "total": 42
}

XHR によるアップロードの進行状況、画像の削除、Amazon S3 の設定については、references/file-storage.md を参照してください。


ローカライズ

unlayer.init({
  locale: 'es-ES',
  textDirection: 'rtl',        // 'ltr' | 'rtl' | null
  translations: {
    es: { Save: 'Guardar', Cancel: 'Cancelar' },
  },
});

検証

// Global validator — runs on all content
unlayer.setValidator(async ({ html, design, defaultErrors }) => {
  return [...defaultErrors]; // Return modified error list
});

// Per-tool validator
unlayer.setToolValidator('text', async ({ html, defaultErrors }) => {
  return defaultErrors;
});

// Run audit on demand
unlayer.audit((result) => {
  // result: { status: 'FAIL' | 'PASS', errors: [{ id, icon, severity, title, description }] }
  if (result.status === 'FAIL') {
    console.log('Issues found:', result.errors);
  }
});

safeHtml(XSS 保護)

unlayer.init({
  safeHtml: true,   // Sanitize HTML via DOMPurify

  // Or with custom options:
  safeHtml: {
    domPurifyOptions: {
      FORCE_BODY: true,
    },
  },

  // WRONG: safeHTML (capital HTML) is DEPRECATED — use safeHtml
});

よくある間違い

間違い修正方法
safeHTML(大文字)safeHtml(キャメルケース)を使用してください — 以前の表記は非推奨です
features.blocks = false でタブが非表示になるブロックは無効になりますが、タブは非表示になりません — tabs の設定を使用してください
非推奨の colorPicker.presets代わりに colorPicker.colors(string[] または ColorGroup[])を使用してください
ファイルマネージャーに user.id がないファイルマネージャーでは init に user.id が必要です
Project Secret がフロントエンドに公開されている絶対にクライアントコードにシークレットを含めないでください — HMAC をサーバー側で生成してください
マージタグの構文が一致しないテンプレートエンジンに合わせてください:{{var}}(Handlebars)、${var}(JS)、{% %}(Jinja)

トラブルシューティング

問題修正方法
マージタグが表示されないsetMergeTags() が editor:ready の後に呼び出されているか、init() に渡されているか確認してください
HMAC 署名が拒否されるuser.id が署名した値と完全に一致していること、およびシークレットが正しいことを確認してください
ファイルマネージャーが空で表示されるuser.id が設定されていること、userUploads.enabled = true であること、プロバイダーが正しい形式を返すことを確認してください
テーマが適用されないinit の後に unlayer.setAppearance({ theme: 'modern_dark' }) または unlayer.setTheme('modern_dark') を使用してください

有料機能

機能有効にする方法
カスタム CSS/JSinit で customCSS、customJS を設定
表示条件setDisplayConditions()
スタイルガイドsetStyleGuide()
画像/PDF/ZIP のエクスポートCloud API key が必要
AI 機能features.ai
コラボレーションfeatures.collaboration

Resources

コメント