Zenn
🌊

HTMLを書かずに装飾!MOSHのリッチエディタ導入全貌

に公開

リッチエディタ導入で、HTMLいらずの快適ライティングを実現

こんにちは、MOSHエクスプレスチームの @liao です。

今回のブログでは、リッチエディタ導入について、背景や導入理由、利用ライブラリ、実装内容、そして今後の展望を詳しくご紹介します。HTMLの知識がなくても、誰でも直感的にテキストを装飾できるようになりました。

背景・導入の目的

1. クリエイターの負担軽減

以前は、コンテンツの説明文やブログを装飾する際にHTMLタグの直書きが必要でした。
そのため、

  • HTMLが苦手なクリエイターは難しく感じる
  • 不要なタグや誤った書き方によるデザイン崩れ
  • サポートチームへの問い合わせ増

といった課題が生じていました。今回リッチエディタを導入することで、HTMLを書かずに太字や下線、見出し、画像・動画埋め込みなどが直感的に行えます。

2. サービス移行や更新時のコスト減

既存のHTMLコードをそのまま修正する場合、特殊なタグや独自仕様を理解する必要があり、クリエイター同士の引き継ぎやサポートコストも高くなりがちでした。リッチエディタ上で直接修正できるようになれば、

  • コードの誤りによるデザイン崩れリスクを低減
  • 更新作業やサポート対応がシンプルに
  • 将来的な拡張やサービス移管がスムーズになる

といった利点を期待できます。

3. ゲストの学習体験向上

見出しや強調表示、箇条書きなどを活用すると、ゲストが読み進めやすいコンテンツを提供できます。MOSHは学習・コミュニティの場としても使われているため、「読みやすい・わかりやすい」 は非常に重要なポイントです。

選定したライブラリ「Quill」の理由

リッチエディタを実装する方法はさまざまありますが、MOSHではQuillを採用しました。主な理由は次のとおりです。

  1. OSS かつコミュニティが大きい
    導入事例が豊富で、ドキュメントやサンプルが充実しているため、開発時の学習コストが比較的低いです。

  2. Delta形式でのデータ管理
    Quill内部で使用されるDelta(デルタ)形式をJSONとして保存できるため、将来的に別のフレームワークへの移行や機能拡張がしやすい仕組みになっています。

  3. シンプルに最低限の機能が揃う
    “Snow”テーマなど標準のUIが使いやすく、ボタン配置や機能の拡張もシンプルな設定で実現できます。

実装内容と工夫したポイント

1. 新規コンテンツからリッチエディタを導入

まずは新しく作成するコンテンツの説明欄にリッチエディタを適用しました。
既存コンテンツについては大きな改修コストを避けるため、当面は従来通りHTMLテキストエリアとして残し、並行運用の形をとっています。

2. 出来上がったエディタはこちら!

「ここに見出しや文字装飾が簡単にできるツールバーが配置されるので、HTMLコードが不要!」というイメージをつかんでいただくために、実際の画面をお見せします。

適用前 (Before) 適用後 (After)
適用前スクリーンショット 適用後スクリーンショット
こちらがリッチエディタ導入前の画面です。 こちらがリッチエディタ導入後の画面です。

上記のように、見出し切り替えや太字・下線、箇条書きなどがワンクリックで利用できるほか、画像アップロードやVimeo動画の挿入機能も搭載しています。

3. 対応機能

現在、リッチエディタで利用できる主な機能は以下のとおりです。

  • 見出し(H1, H2, H3) 切り替え
  • 太字、下線、取り消し線
  • 左寄せ・中央寄せ・右寄せ・均等割り
  • 文字色変更(5色)
  • 箇条書きリスト・番号リスト
  • ソースコードブロック
  • リンク挿入
  • 画像アップロード・挿入
  • Vimeo埋め込み

特に、画像アップロードVimeo埋め込み はリリース直後から需要の高い機能でした。

4. 画像アップロードの仕組み

画像挿入にはQuill標準のアップローダー機能をカスタマイズし、以下のようなフローを取り入れています。

  1. 画像を選択すると、まず “アップロード中”のプレビュー用Blot (UploadingImageBlot) を挿入し、エディタ内に暫定表示。
  2. サーバーへ画像をアップロード(署名付きURLを用いてクラウドストレージに直接PUT)。
  3. アップロードが成功すると、“本番表示用Blot” (MoshImageBlot) に差し替えて最終的なURLやメディアIDを埋め込む。
  4. 失敗時はプレビューを削除し、エラーメッセージを表示。

アップロード中でもクリエイターが挿入した画像を即座に確認できるため、ストレスなく作業を進められます。

5. Vimeo埋め込みの実装

動画コンテンツを扱うため、Quillのツールバーに「vimeo」ボタンを追加しました。
以下のステップでiframeタグを直書きせずに安全な埋め込みを実現しています。

  1. ユーザーがVimeoのURLを入力。
  2. バリデーション後、 player.vimeo.com/... の正規化されたURLを生成。
  3. 独自Blotを用いてエディタ内に動画プレイヤーを埋め込む。

6. Delta形式でデータを保存

エディタの内容は、QuillのDelta(オブジェクト) をJSON化してサーバーに保存し、表示時にDelta→HTMLの変換を行います。
これによって、

  • 生のHTMLを扱わず、セキュリティリスクを低減
  • 別のエディタに乗り換える際にも比較的容易
  • 将来的な差分管理やバージョン管理がしやすい

といったメリットを得ています。

コードサンプル(抜粋)

実際のコードはBlotの定義やアップロードサービスなどが複数モジュールに分かれていますが、こちらにポイントを示すコードの一部を抜粋します。フレームワークはAngularを採用しています。

import Quill, { Delta } from "quill";

@Component({
  selector: "mosh-rich-editor",
  templateUrl: "./mosh-rich-editor.component.html",
  styleUrls: ["./mosh-rich-editor.component.scss"],
})
export class MoshRichEditorComponent implements AfterViewInit {
  private quill?: Quill;

  ngAfterViewInit() {
    this.quill = new Quill(this.editor.nativeElement, {
      theme: "snow",
      modules: {
        toolbar: {
          container: [
            [{ header: [1, 2, 3, false] }],
            ["bold", "underline", "strike"],
            [{ color: [false, "#e10011", "#187e1B", "#005dc1", "#8834f8"] }],
            [{ align: [] }],
            [{ list: "bullet" }, { list: "ordered" }],
            "image",
            "code-block",
            "link",
            "vimeo", // カスタムボタン
          ],
          handlers: {
            vimeo: () => this.handleVimeoInsert(),
          },
        },
        uploader: {
          mimeTypes: ["image/jpeg", "image/png"],
          handler: (range, files) => {
            this.handleImageUpload(range, files[0]);
          },
        },
      },
    });

    // テキスト変更イベント
    this.quill.on("text-change", () => {
      const delta = this.quill?.getContents() || new Delta();
      // サーバー送信やフォーム制御に利用
    });
  }

  // Vimeo埋め込み処理
  private handleVimeoInsert() {
    // 1. ダイアログでURLを入力→バリデーション
    // 2. Blotを用いてVimeoプレイヤーを挿入
  }

  // 画像アップロード処理
  private handleImageUpload(range, file: File) {
    // 1. アップロード中Blotを挿入
    // 2. サーバーにアップロード(Observableで進捗を監視)
    // 3. 成功時はアップロード中Blotを削除 → 本番用Blotに切り替え
  }
}

今後の展望

  1. 機能の段階的拡充
    • 画像にキャプションを入れたい
    • Vimeo以外の動画プラットフォーム対応
    • 表組みや水平線などの追加要素
  2. スマホUIの向上
    ツールバーのレイアウト最適化や画像アップロードUIをさらに洗練し、モバイル端末からも快適に操作できるようにしていきます。
  3. 既存コンテンツの移行
    旧HTMLエディタで書かれたコンテンツを、必要に応じてリッチエディタに移行できるか調査を進めます。移行ツールの作成や互換性確保など、運用状況を見ながら段階的に検討する予定です。

まとめ

リッチエディタ導入により、MOSHでのコンテンツ作成が格段にしやすくなりました。
HTMLを書くハードルが下がるだけでなく、セキュリティ面や移行時の負担軽減など、運用面でのメリットも大きいと感じています。
特に画像アップロードVimeo埋め込みが強化されたことで、クリエイターのみなさんの表現の幅が広がり、ゲストにとっても見やすいコンテンツが増えていくのではないかと期待しています。

私たちMOSH開発チームは、今後もクリエイターとゲスト両方の体験を良くするために、リッチエディタ機能の拡充周辺システムの改善を継続して行っていきます。ぜひこれからのアップデートにもご注目ください!

MOSH

Discussion

ログインするとコメントできます