Contentful Custom App入門 - CMSダッシュボードのUI拡張からサーバーサイド処理まで、できることを解説してみる
ベルリンオフィスの小西です。
ヘッドレスCMSのContentfulには「Custom App」という拡張の仕組みがあります。ダッシュボードのフィールド入力UIを差し替えたり、外部サービスとの連携処理を組み込んだり、コンテンツのライフサイクルに合わせた自動処理を走らせたり、やれることの幅がかなり広いです。
ただ、公式ドキュメントだと個々の機能の説明は充実している一方、「全体としてどういう構成なのか」「何がどこまでできるのか」が掴みにくい印象がありました。
この記事では、Custom Appの概念を整理しつつ、構成要素とそれぞれの役割、開発時に押さえておきたいポイントをまとめてみます。
Contentful Custom Appとは
Contentfulは、APIファーストでコンテンツを管理・配信するヘッドレスCMSです。Webサイトやアプリの記事や情報管理に使われることが多く、管理画面(ダッシュボード)上でエントリーを作成・編集し、APIを通じてフロントエンドに配信する、というのが基本の使い方です。
Custom Appは、このContentfulのダッシュボードや処理パイプラインを独自に拡張する仕組みです。以前は「UI Extension」という名前で提供されていた機能が、現在のApp Frameworkに統合されています。
代表的なユースケース
ダッシュボードのUI拡張
フィールドの入力UIを独自のものに差し替えることができます。たとえば、独自のエディタを導入したり、テキストフィールドの代わりにカラーピッカーを表示したり、地図上でピンを打って座標を保存したり、外部サービスのデータを検索・参照できるUIにしたり・・・。サイドバーに補助情報やアクションボタンを追加することもできます。


外部サービス連携
外部APIからデータを取得してContentful上で参照・プレビューしたり、コンテンツの公開時に外部システムへ通知・同期するような処理を組み込めます。
コンテンツワークフローの自動化
公開前のバリデーションや承認フローを組み込んだり、エントリーの公開をトリガーにAI翻訳や画像変換を走らせるといった、イベント駆動の自動処理が実現できます。
App Frameworkの全体像
Custom Appを構成する要素は、大きく分けて以下の4つです。
| 要素 | 役割 | 動作する場所 |
|---|---|---|
| Locations | AppをダッシュボードUIのどこに表示するか | ブラウザ |
| App SDK | Appのフロントエンドから、ContentfulのデータにアクセスするためのAPI | ブラウザ |
| Functions | Appのバックエンドで動くサーバーサイドロジック。外部APIキーなどシークレットを扱う処理はこちら | サーバー(Contentfulホスト) |
| Forma 36 | Contentful公式のデザインシステム。AppのUIをContentful本体と統一するためのコンポーネントライブラリ | ブラウザ |
ポイントは、App SDK(フロントエンド)とFunctions(バックエンド) の2層構成になっていること。ダッシュボード上のUI操作はApp SDKで、シークレットの管理や外部API呼び出しなどサーバー側でやるべき処理はFunctionsで、という切り分けです。
Forma 36は必須ではありませんが、使うとContentful本体と見た目の統一感が出ます。
Appのホスティング
Custom Appのフロントエンド部分をどこでホストするかは、3つの選択肢があります。
- Contentfulにデプロイ: Contentfulにバンドルをアップロードしてホストしてもらう方法。インフラの管理が不要で、障害点の増加も抑えられるため、本番運用ではこれが便利で安心な印象です
- 外部URLエンドポイント: 自前のサーバーやCDN経由でホストし、URLをContentfulに登録する方法。既存のインフラに載せたい場合や、特殊な要件がある場合に
- localhost: ローカル開発用。
localhostのURLを登録して、手元で動かしながら開発・デバッグできる
また、Contentful Marketplaceには公式やサードパーティが作成し、Contentfulが承認したMarketplace Appも公開されています。用途に合うものがあれば、自前で開発せずにそのまま導入できるので手っ取り早いです。

Locations - UIのどこに差し込むか
Locationは、Appがダッシュボード上のどこに表示されるかを決めるものです。Custom App開発で最初に考えることになる設計判断でもあります。
| Location | 配置される場所 | 使いどころ |
|---|---|---|
| App Configuration | Appのインストール時・設定画面 | App全体の設定値を管理する |
| Entry Field | エントリーのフィールド入力UI | フィールドのUI・入力方法を差し替える |
| Entry Sidebar | エントリー編集画面のサイドバー | 補助情報やアクションボタンを表示する |
| Entry Editor | エントリー編集画面全体 | 新しい編集タブをまるごと追加する |
| Page | Contentful内の独立したページ | ダッシュボードやレポート画面を追加する |
| Dialog | モーダルダイアログ | 検索・選択UIなどを別ウィンドウで表示する |
| Home | Contentfulホーム画面 | ホーム画面にカスタムウィジェットを追加する |
Entry Fieldの例:

Entry Sidebarの例:

1つのAppで複数のLocationを持つこともできます。たとえば、App Configurationで設定画面を用意しつつ、Entry Fieldでフィールドの入力UIを差し替える、という構成が一般的です。
App SDK - Appから何にアクセスできるか
App SDKは、LocationにレンダリングされたApp(React等で構築)がContentfulとやり取りするためのクライアントライブラリです。Appの初期化時にSDKオブジェクトを受け取り、そこから現在のフィールド値やエントリーの情報にアクセスします。
主要なAPIをいくつか紹介します。
| API | できること |
|---|---|
sdk.field |
現在のフィールド値の取得・更新 |
sdk.entry |
エントリー全体のフィールドへのアクセス |
sdk.space |
スペース内のエントリー・アセットの検索・作成 |
sdk.notifier |
UI上に通知(成功・エラー等)を表示 |
ここで重要なのがCMA Adapterです。App SDKにはContent Management API(CMA)を直接呼ぶためのアダプターが組み込まれており、開発者ではなく各ユーザー自身の権限で操作が実行されます。つまり、ユーザーが自分の権限以上の操作を実行することを防げるため、App側で独自に権限チェックを実装する必要がありません。
Functions - サーバーサイドの処理
Functionsは、Contentfulがホストするサーバーレス実行環境です。Appにバックエンドロジックを持たせることができ、外部APIキーなどのシークレットを安全に扱えます。
3種類のFunctionがあります。
App Event Functions
エントリーの公開・更新・削除など、コンテンツのライフサイクルイベントを購読して処理を実行します。
用途としては、イベントのフィルタリング(特定のコンテンツタイプだけ処理する)、リクエストボディの変換、外部サービスへの通知といった自動処理が挙げられます。
App Action Functions
Appのフロントエンドや他のAppから呼び出せる、汎用的なバックエンド処理です。外部APIとの連携やデータの加工など、フロントエンドに置けない処理をここに書きます。
認証情報の管理にはApp Identitiesという仕組みが用意されていて、シークレットをApp側で安全に保持できます。
Functions on Delivery(GraphQL)
GraphQL配信リクエストの経路上で動作するFunctionです。コンテンツの配信時にリアルタイムで加工・統合を行えます。たとえば、外部データソースのコンテンツをContentfulのレスポンスに合成する、といった使い方ができます。
開発・実践まわり
Custom Appの環境構築やローカルでの立ち上げ・開発手順については、以前記事で紹介しているのでぜひご覧ください。
本記事では、開発時に押さえておきたいベストプラクティスをいくつか紹介します。
権限設計
Contentfulの権限はOrganization / Space / App Definitionの各レベルで設定されます。Appに無制限の権限を与えることもできますが、前述のCMA Adapterを使えばユーザー自身の権限で操作が実行されるため、最小権限の原則に沿った設計がしやすいです。
まずはCMA Adapter経由でユーザー権限に委ねる構成にしておき、どうしてもApp独自の権限が必要な場合だけ個別に設定する、というアプローチが無難です。
フロントエンドとバックエンドの切り分け
認証情報(APIキー等)が必要な処理はバックエンドのFunctionsに寄せましょう。フロントエンド(Location側)にシークレットを持たせてはいけません。ブラウザで動くAppのコードはユーザーから見えるため、シークレットが漏洩するリスクがあります。
フィールドバリデーション
カスタムUIを作る場合でも、Contentful側で設定済みのバリデーションルール(必須チェック、文字数制限など)を利用できます。
sdk.field.onSchemaErrorsChanged() でバリデーションエラーの変化を購読し、独自UIにエラー状態を反映できます。ただし、sdk.field.setInvalid() はフィールドの見た目(赤いエラーバー)を変えるだけで、公開をブロックする機能は持っていない点にご注意ください。
障害時のフォールバック
Entry Fieldとして個別のフィールドUIを差し替えた場合、そのAppに障害が起きると(特に外部でホストしている場合)フィールドの操作ができなくなります。
一方、Entry Editorとして新たに編集タブを追加する構成にしておけば、障害時にAppを外すだけで元のフィールドUIで編集が続行できます。
Forma 36の活用
Contentful公式のデザインシステム「Forma 36」を使うと、ボタン、テキストフィールド、テーブルなどのUIコンポーネントが揃っていて、Contentful本体と見た目の一貫性を保てます。割と破壊的な変更も入ることがあり注意が必要ですが、自前でCSSを書く手間も省けるので、こだわりがなければ使っておくのが楽です。
まとめ
Custom Appは、Locations(UIのどこに出すか)、App SDK(フロントエンドでのデータアクセス)、Functions(サーバーサイド処理)という3つの柱で構成されています。
標準の機能では手が届かない部分(=入力UIのカスタマイズ、外部サービスとの連携、イベント駆動の自動処理)をContentfulの中に組み込めるのが強みです。
最初から全部使う必要はなく、まずはLocationとApp SDKだけで小さなAppを作ってみて、シークレットの管理やイベント処理が必要になったらFunctionsを足す、という段階的なアプローチが取り組みやすいと思います。
クラスメソッドを通じてCOntentfulをご利用いただいているお客様は、こちらのCustom Appの利用も可能です。ぜひ担当者にご相談ください。






