ヘッドレス CMS 「Directus」 は柔軟でわかりやすい投稿画面を手に入れたい時に使いたい。導入から記事投稿のベストプラクティスへのヒント


こんにちは、Gaji-Labo フロントエンドエンジニアのたにもとです。

Webサイトを運営する上で、コンテンツの更新頻度が高く、変更の容易さを重視したい場合にヘッドレスCMSという選択が近年のトレンドです。

今回は数あるヘッドレスCMSの中から「Directus」に焦点を当て、特にメディアサイトの記事投稿にフォーカスして深掘りしていきます。

ヘッドレス CMS の選定やこれからDirectusでコンテンツ管理を始めようとしている方の手助けになれば幸いです。

記事管理をする際の Directus コレクションの設計

Directusでは、記事や画像などのコンテンツを「コレクション」という単位で管理します。
データベースのテーブルのようなものだと考えていただくと分かりやすいでしょう。
また、コレクションの中に設置する入力項目を「フィールド」と表現します。

本記事では、以下の項目について詳しく解説します。

記事本文の入力形式を選ぶ:Block Editor、Markdown、WYSIWYG

どのような入力形式を選ぶかは、記事作成の効率や柔軟性に大きく影響します。
主に以下の3つの選択肢があります。

  • Block Editor: WordPressのブロックエディターのように、文章や画像、見出しなどをブロックとして組み合わせて記事を作成する形式です。
  • Markdown: 近年多くのツールで利用されている記法で文章構造を表現する形式です。
  • WYSIWYG: ツールバーを使って文字の装飾や画像の挿入などを行う形式で一番多機能な入力形式だと言えます。

これらを選ぶ時に以下のような観点で選ぶと良いと考えています。

  • 社内の他プロジェクトでの利用状況: 既に社内で慣れ親しんでいるツールがあれば、学習コストを抑えられます。
  • 外部ライターへの依頼計画: 外部のライターに記事作成を依頼する場合、採用のハードルにならない形式を選ぶとスムーズです。
  • 社内の記事作成担当者のスキル: 記事を作成する担当者が、どの入力形式に慣れているかを考慮します。
  • 入力の柔軟性への許容度: どこまで自由な表現を許容するかによって選択肢が変わります。柔軟性が高いほど表現の幅は広がりますが、デザインの統一感を保つためのルール作りが重要です。

各入力形式のメリット・デメリット

入力形式メリットデメリット
Block EditorWordPress を利用したことがある場合直感的で操作しやすい。
決められたパーツの中から挿入パーツを選ぶのでデザイン統制しやすい。
決められたパーツしか挿入できないので柔軟な変更には対応できない。
Markdown他ツールで利用しているのであればシンプルで扱いやすい。
Markdownを変換するプラグインが豊富。
リッチなデザイン表現は難しい。
書き手にマークダウンで記述できるスキルが必要。
WYSIWYG視覚的に分かりやすく、非技術者でも扱いやすい。ツールバーが充実しており機能が豊富。自由度が高すぎるのでサイト全体のデザインが崩れる可能性がある。運用ルールもしくは、データを受け取った側で予期せぬ入力に対するエラーハンドリングを検討の必要がある。

どの入力形式でもデータは string 型で受け取ることになります。
テキストの情報を検知して適切なコンポーネントに置き換える処理が必要です。

柔軟なコンテンツ構成を実現するためのフィールド設計

コンテンツの入力フィールドを1つにまとめてしまうと、記事の途中に特定のデザインのパーツや集客用のボタンを挿入したい場合、または SEO 施策でコンテンツの順番を入れ替えたい場合に手間がかかります。

通常であればシンプルなテキストフィールドで本文を作成します。

しかし、(M2A)ビルダーフィールドを利用することでブロックエディターのように記事本文を作成できます。

これにより、以下のようなメリットがあります。

  • 柔軟なコンテンツ配置: 記事の途中に特定のブロックを挿入したり、順番を入れ替えたりできます。
  • 再利用性の向上: 同じブロックを複数の記事で使い回すことができます。

(M2A)ビルダーフィールドはデータの受け取り側で collection の値にDirectus 側で設定した名称が表示されます。
これによってデータを受け取るアプリケーション側で要素の判別が容易になります。

ただし、対応するパーツのコンポーネント(pタグやhタグ、table タグなど)をフロントエンド側で別途管理する必要があります。また、Directus の管理画面上では、コンテンツの全体像を把握するために各ブロックをクリックして中身を確認する必要があるため、多少の不便さを感じる可能性があります。

テンプレート化した情報を記事に挿入したい

メディアサイトでは、執筆者情報などの決まったフォーマットで繰り返し表示したい情報がよくあります。Directus では、「Many-to-One」や「Many-to-Many」といったリレーションシップフィールドを利用することでこれらの情報を効率的に管理し、再利用できます。

例えば、執筆情報なら「執筆者の名前」「プロフィール」「写真」などを管理するコレクションを作成します。「Many-to-One」や「Many-to-Many」などのフィールド記事投稿用コレクションに設置することで登録した情報から選択し、コンテンツとして挿入できます。

繰り返し利用するコンテンツがあるなら別のコレクションで管理し、情報を一元管理することで情報に変更があった場合に容易に対応できるメリットがあります。

特定の条件で入力項目を出しわけ、管理画面をスッキリさせる

1つのコレクションで複数のカテゴリやタイプの記事を管理する場合、すべての記事に共通ではない入力項目が多くなり、管理画面が煩雑になることがあります。
記事作成時に不要な項目が表示されていると、ノイズとなり作業の妨げになってしまう可能性があります。

Directusでは、この課題を解決するために「グループ(Groups)」と「条件(Conditions)」の機能を利用できます。以下の手順で対応します。

1. 記事タイプを判別するフィールドの作成
記事のタイプを判別するためのフィールド(例: article_type)をラジオボタンなどで作成します。

2. 関連するフィールドのグルーピング
特定の記事タイプにのみ必要な入力項目を「Raw Group」を利用してまとめます。

作成したグループにフィールドをドラック&ドロップでフィールドを移動させ完了です。

3. 表示条件の設定:
作成したグループに対して、article_type フィールドの値に基づいて表示・非表示を切り替える条件を設定します。
グループの右上の3点リーダー選択して編集画面に入ります。
メニューの「条件」を選択して、新規作成を選択します。

条件の設定を簡略化するため、「blog」が含まれない時は非表示の設定にします。

これにより、記事タイプを選択すると、そのタイプに必要な入力項目だけが表示され管理画面が見やすくなります。

Directus からのデータ取得と出力

アプリケーション側で Directus からのデータを取得し出力します。
今回は DirectusのSDK(Software Development Kit)を使ってデータの取得と出力をします。

// Directus SDKを使って記事データを取得する例
import { ... } from "@directus/sdk";

const post = await directus.request(
  readItems("Pages", { // "Pages"は記事コレクションのID
    fields: [
      "*", // すべての基本フィールドを取得
      {
        blocks: [ // "blocks"フィールド(関連コレクション)を展開
          "*", // ブロックの基本フィールドを取得
          {
            item: { // ブロックの中身(各ブロックコレクション)を展開
              block_heading: ["*"], // block_headingコレクションの全フィールドを取得
              block_content: ["*"], // block_contentコレクションの全フィールドを取得
            },
          },
        ],
      },
    ],
  })
);

(M2A)ビルダーで作成したフィールドのデータを取得する場合は、上記のように記述すると取得することができます。

// 取得したデータをフロントエンドで処理する例
const post = await getBlogPost(params.id);

post.blocks.forEach((block: any) => {
  // ブロックのコレクション名に応じてコンポーネントを出し分ける
  if (block.collection === "block_heading" && block.item) {
    // 例: Headingコンポーネントにデータを渡してレンダリング
    bodyComponents.push(<Heading data={block.item} />);
  } else if (block.collection === "block_content" && block.item) {
    // 例: ContentTextコンポーネントにデータを渡してレンダリング
    bodyComponents.push(<ContentText data={block.item} />);
  }
  // その他のブロックタイプも同様に追加
});

// レンダリングされたコンポーネント群をまとめて返す(例: return <>{bodyComponents}</>;)
return bodyComponents;

取得したデータの collection プロパティをチェックし、どのタイプのブロックであるかを判断します。
対応するフロントエンドのコンポーネントにデータを渡してレンダリングすることで、柔軟な記事表示が可能になります。

まとめ

Directus に限ったことではありませんが、ヘッドレス CMS を利用したサイトの構築は入力形式一つとっても中長期的な運用に耐えられるかを検討する必要があります。
本記事の内容がプロジェクトの一助になれば幸いです。

Directus についてさらに詳しく知りたい場合は、公式ドキュメントDirectus の動画もぜひ参考にしてみてください。

実運用も考えるとCMS 導入は検討することが多く難しいと考えています。
Gaji-Labo は事業やチームのメリットを一緒に考えた CMS の設計・構築ができるメンバーも在籍しています。もしお悩みの方がいたら、ぜひ一度ご相談ください!

Gaji-Labo は Next.js, React, TypeScript 開発の実績と知見があります

フロントエンド開発の専門家である私たちが御社の開発チームに入ることで、バックエンドも含めた全体の開発効率が上がります。

「既存のサイトを Next.js に移行したい」
「人手が足りず信頼できるエンジニアを探している」
「自分たちで手を付けてみたがいまいち上手くいかない」

フロントエンド開発に関わるお困りごとがあれば、まずは一度お気軽に Gaji-Labo にご相談ください。

オンラインでのヒアリングとフルリモートでのプロセス支援にも対応しています。

Next.js, React, TypeScript の相談をする!

Gaji-Labo Culture Deck

Gaji-Laboでは、 Next.js 経験が豊富なフロントエンドエンジニアを募集しています

弊社では Next.js の知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違う Gaji-Labo を味わいに来ませんか?

Next.js の設計・実装を得意とするフロントエンドエンジニア募集要項

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!


投稿者

フロントエンドエンジニア。 事業会社で LPO や EFO のサービス改善を経験し、Gaji-Labo に入社。 関わってくださる人により良い選択を提供できることを目指し日々奮闘しています。 3度の飯よりアニメが好き。