microCMS

microCMSの拡張フィールドを利用したMarkdownの入稿環境をつくる

この記事は公開後、1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、フロントエンドエンジニアの森茂です。

microCMSにはMarkdown専用のエディターは用意されていないため、Markdownの情報を入稿したい場合はMarkdown記法が利用できるリッチエディターを利用する必要があります。ただし登録したデータはリッチエディターの形式に変換されてしまうため、Markdownのまま入稿データの管理を行うことはできませんでした。

しかしながらmicroCMSには拡張フィールド(旧iframeフィールド)というものがあり、自身で用意する必要はありますがオリジナルのアプリケーションを拡張フィールド内で開き、各種データを共有することが可能になっています。

今回はMarkdownでデータを管理したい方向けに、microCMSの拡張フィールドを利用したMarkdownエディターの利用例をご紹介します。

拡張フィールドについて

拡張フィールドの活用方法の例としては、Google MapsやAmazonの書籍データと連携した例などが公式ブログにも掲載されています。拡張フィールドの仕様などについてはこちらも参照ください。


拡張フィールドから利用するMarkdownエディターを用意する

拡張フィールドはiframeを経由してローカル環境またはWeb上のアプリケーションとデータを連携する仕組みになっています。まずはMarkdownエディターをローカルの開発環境で用意し、microCMSの管理画面からローカル環境を利用するよう準備をします。
今回はNext.jsと実装方法もシンプルでNext.jsに対応しているMarkdownライブラリであるMarkdown Editor for Reactを利用してMarkdownエディターアプリケーションを用意します。

Next.js v13のインストール

$ npx create-next-app@latest --ts


必要なライブラリのインストール

Next.jsでMarkdown Editorを動かすにはライブラリ@uiw/react-md-editorの他にnext-remove-importsのインストールと設定の追加が必要となります。公式のドキュメントを参考に実装します。

$ npm install next-remove-imports @uiw/react-md-editor

next-remove-importsの設定をnext.config.jsに追記します。

// next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
 reactStrictMode: true,
 swcMinify: true,
};

const removeImports = require("next-remove-imports")();

module.exports = removeImports({
 ...nextConfig,
});

あわせてmicroCMSの拡張フィールドを手軽に利用できるmicrocms-field-extension-reactをインストールしておきましょう。

$ npm install microcms-field-extension-react

これで事前の準備は完了です。

Next.jsでMarkdownエディターを実装する

Next.jsでMarkdown Editor for Reactを利用するにはDynamic importを利用する必要があります。またmicrocms-field-extension-reactを利用してmicroCMSの拡張フィールドとデータの連携ができるようにします。

// pages/index.tsx

import { useEffect, useState } from "react";
import dynamic from "next/dynamic";
import { useFieldExtension } from "microcms-field-extension-react";
import "@uiw/react-md-editor/markdown-editor.css";
import styles from "../styles/Home.module.css";

// Markdown Editor for ReactはSSRで利用できないためdynamic importで読み込む必要がある
const MDEditor = dynamic(import("@uiw/react-md-editor"), {
 ssr: false,
 loading: () => <div>initializing...</div>,
});

// 利用しているmicroCMSのURLを設定
const origin = "https://xxxxxx.microcms.io";

const IndexPage = () => {
 const [markdown, setMarkdown] = useState<string | undefined>();
 // microCMSのフィールド拡張を利用するためのhook
 const { data, sendMessage } = useFieldExtension("", {
  origin,
  height: 540,
 });

 useEffect(() => {
  if (!markdown) {
   setMarkdown(data);
  }
 }, [data, markdown]);

 return (
  <div data-color-mode="light" className={styles.container}>
   <MDEditor
    value={markdown}
    onChange={(value) => {
     setMarkdown(value);
     sendMessage({
      data: value,
     });
    }}
    height={540}
    textareaProps={{
     placeholder: "Please enter Markdown text",
    }}
   />
  </div>
 );
};

export default IndexPage;


動作の確認

これで準備は完了です。ローカル環境で開発サーバーを起動します。Next.jsのデフォルト設定ではhttp://localhost:3000でサーバーが起動します、この設定がmicroCMSのAPIスキーマと同じ値になっているかをあらかじめ確認しておいてください。

$ npm run dev

開発サーバーが問題なく起動できたらmicroCMSからコンテンツ投稿画面を開いて確認してみましょう。左側にMarkdown記法で記載すると右側にリアルタイムでプレビューが表示されるはずです。

もし、下記のような画面になってしまった場合はmicroCMSの管理画面とローカルサーバーとうまく通信ができていない状態です。起動状況やポート番号など確認してみてください。

これでMarkdownで投稿、編集ができるようになりました。API取得側でもそのままMarkdownのデータが取得できるので好きなようにスタイルを調整して利用してみてください。

Cloudflare R2を利用した画像の投稿

Markdownでの入稿環境ができたところで、どうせなら画像もドラッグ・アンド・ドロップで投稿したいですよね。AWS S3と互換性のありさらに通信量が無料なCloudflare R2へアップロードできるように拡張していきます。なお、事前にCloudflareのアカウント作成が必要となります。

Cloudflare R2の無料枠

  • 10GB/月
  • 書き込み 100万リクエスト/月
  • 読み取り 1000万リクエスト/月

Cloudflare R2バケットの準備

CloudflareのダッシュボードからR2のバケットを新規に作成します。

バケットは外部から閲覧可能な状態にする必要があるのでパブリックアクセスを許可し公開バケットURLを取得する必要があります。またNext.jsからAWS-SDKを利用してR2バケットへファイルをアップロードするためS3 APIもメモしておいてください。

アクセスを許可を押下すると公開バケットURLを取得することができます。

Cloudflare R2 APIトークンの取得

さらにAPIへ接続するためのトークンを取得する必要があります。

アプリケーションから書き込む必要があるため編集権限を設定します。

作成完了後アクセスキーIDシークレットアクセスキーが表示されるので忘れずにメモしておいてください。この画面を閉じると再表示することはできません。

これでR2バケットの準備は完了です。次にアプリケーションを拡張していきます。

画像アップロード機能の実装

必要なライブラリのインストール

R2バケットへのアップロードへaws-sdkを利用します。また画像ファイルのパース処理のためにformidableを、画像ファイルをユニーク名に変更するためにcuidを利用します。

npm install @aws-sdk/client-s3 formidable cuid
npm i --save-dev @types/formidable


環境変数の用意

Cloudflare R2バケット名やAPI、トークンなど各種シークレットを.env.localファイルに記載しておきます。

NEXT_PUBLIC_MICROCMS_ORIGIN=https://xxxx.microcms.io
# Cloudflare R2
NEXT_PUBLIC_R2_BUCKET_URL=https://xxxxxxxxxxxxxxxxx.r2.dev
NEXT_PUBLIC_BUCKET_NAME=xxxxxxxxxxxxxxxx
R2_ENDPOINT=https://xxxxxxxxxxxxxxxxxx.r2.cloudflarestorage.com
R2_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
R2_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


Next.jsアプリケーションへの実装

R2へのアップロードにはMarkdownエディタへ画像ファイルをドラッグ・アンド・ドロップした際にNext.jsのAPI routeへアクセスし画像ファイルをアップロードするよう実装を行います。
pages/index.tsxpages/api/upload.tsutils/fileUploader.tsutils/insertToTextArea.tsutils/onImagePasted.tsに作成して実装を行っています。
MDEditorコンポーネントにonDropを追加しファイルの処理を行っています。その他詳細についてはソースコードのサンプルをご確認ください。

// pages/index.tsx

onDrop={async (event) => {
  event.preventDefault();
  await onImagePasted(event.dataTransfer, setMarkdown);
}}

サンプルコード

https://github.com/himorishige/microcms-iframe-markdown-example

動作の確認

管理画面から画像ファイルをドラッグ・アンド・ドロップで配置してみるとカーソルの位置に画像を挿入することができるようになります。また画像のURLにはR2の公開URLが設定されており、画像ファイルも公開できるようになりました。なおファイル名はcuidを利用したユニークな名称となるため常に新しい画像としてアップロードされます。一度アップロードした画像はパブリックに公開されるため削除したい場合はR2のダッシュボードから削除する必要があります。

APIのレスポンス

microCMSのコンテンツAPIからのレスポンスは下記のようになります。今回ですとmarkdownというフィールド名にしているので少々紛らわしいですがmarkdownの値にmarkdown形式がテキストとしてそのまま入ります。これらをフロント側では好きなように処理して活用できると思います。

{
    "contents": [
        {
            "id": "ak_5p9k1s",
            "createdAt": "2022-11-22T07:43:31.569Z",
            "updatedAt": "2022-11-22T09:50:59.981Z",
            "publishedAt": "2022-11-22T07:43:31.569Z",
            "revisedAt": "2022-11-22T09:50:59.981Z",
            "title": "Markdown",
            "markdown": "# test\n\n- list\n- list\n\n![](https://pub-de421d74e6014b45aadb354a19610d9e.r2.dev/images/clas0us8c00003b6q43xhqml3.webp)\n"
        }
    ],
    "totalCount": 1,
    "offset": 0,
    "limit": 10
}

さいごに

いかがでしたでしょうか、拡張フィールドの活用方法の1つの例としてMarkdownの入稿環境をご紹介しました。
今回の実装では個人環境で利用することを想定しているためこのままでは誰でも画像が投稿できてしまったり、ファイル容量の制限などバリデーションもほとんどありません。ただ外部サーバーへ公開をしなくても投稿する関係者にはDockerコンテナとして配布し運用するといった方法なども考えられると思います。microCMSの拡張フィールドを利用した1つの運用アイデアとしてぜひ活用してみてください。

参考サイト

まずは、無料で試してみましょう。

APIベースの日本製ヘッドレスCMS「microCMS」を使えば、 ものの数分でAPIの作成ができます。

microCMSを無料で始める

microCMSについてお問い合わせ

初期費用無料・14日間の無料トライアル付き。ご不明な点はお気軽にお問い合わせください。

お問い合わせ

microCMS公式アカウント

microCMSは各公式アカウントで最新情報をお届けしています。
フォローよろしくお願いします。

  • X
  • Discord
  • github

ABOUT ME

森茂洋
Web制作、開発会社を経て2022年11月にmicroCMSにジョイン。きっとインターネット老人会に所属しています。インフラやWebに関わる技術の探訪が大好きで興味をもった技術は広く深く掘り下げていくことが信念。microCMSではフロントエンドテックリードとして開発チームのサポートを担当。趣味はサイクリングとアイスホッケー、そして甘いもの。