ContentfulでHome画面を自分好みにカスタマイズする方法(Contentful App)

2023.09.20

ヘッドレスCMSのContentfulで、コンソールのHome画面をカスタマイズすることがありました。

この記事ではContentful Appという自作プラグイン機能を使った実装方法を紹介します。

Home画面

デフォルトは↓のような感じ

scr_2023-09-19_1768

アプリの新規作成@Contentful

Contentfulのダッシュボードから、Organizationの管理画面に移動し、[Apps] > [Create app] に進みます。

Screenshot 2023-09-19 at 16.21.20

  • FrontendのURL として `http://localhost:3000` と入力
  • Locationsとして Home にチェックを入れる

Screenshot 2023-09-19 at 16.25.00

Appを[Save]後、[Actions]から[Install to space]へ進みます。

Screenshot 2023-09-19 at 16.27.02

インストール先のSpaceを選択します。

scr_2023-09-19_1763

[Authorize access]でインストールを実行します。

scr_2023-09-19_1764

その後、対象のSpaceから [Settings] > [Home] に移動し、先ほどインストールしたAppを選んで[Save]します。

Screenshot 2023-09-19 at 16.32.49

これでContentful側の開発準備は完了です。

アプリ構築@ローカル

ローカルで、Homeに表示するフロントアプリを作っていきます。

今回の自分の環境。

  • Node.js v18.13.0
    • 対応: v14.15, v16.16 or v18.12
  • create-contentful-app v1.2.126
  • NPM v8.19.3
    • 対応: v6 or later

ローカルでアプリを立ち上げます。

% npx create-contentful-app
? App name my-home
? Do you want to start with a blank template or use one of our examples? Template
? Pick a template React + Vite

% cd ~/my-home
% npm start
VITE v4.3.9  ready in 844 ms
➜  Local:   http://localhost:3000/

この時点でlocalhostにブラウザからアクセスするとwarningメッセージが表示されますが、これでOKです。

scr_2023-09-19_1765

ContentfulのHomeに行ってみましょう。

scr_2023-09-19_1767

Hello homeと表示されています。こちらをカスタマイズしていきます。

Homeに何を置くかですが、今回は「自分が書いた記事の最新5件を取得し、そのままHomeから編集ページに飛べる」ようにしたいと思います。

src/locations/Home.tsx

import {useState, useEffect} from 'react';
import { HomeAppSDK } from '@contentful/app-sdk';
import { Flex, EntryCard, Heading } from '@contentful/f36-components';
import { useSDK } from '@contentful/react-apps-toolkit';
import { EntryProps } from 'contentful-management'

const Home = () => {
  const sdk = useSDK<HomeAppSDK>();
  const userId = sdk.user.sys.id
  const [entries, setEntries] = useState<EntryProps[]>();

  useEffect(() => {
    const params = {
      limit: 5,
      "sys.createdBy.sys.id": userId
    }

    sdk.cma.entry.getMany({
      query: params
    })
    .then((res) => {
      setEntries(res.items);
    })
  }, []);

  return (
    <Flex
      flexDirection="column"
      style={{ margin: '80px auto', maxWidth: '660px' }}>

      <Heading>あなたの最近のポスト</Heading>

      {entries && entries.map((e) => (
      <EntryCard
        key={e.sys.id}
        status={e.sys.publishedAt ? "published" : "draft"}
        contentType={e.sys.contentType.sys.id || ""}
        title={e.fields.title ? e.fields.title["en-US"] : "Untitled"}
        description={e.sys.publishedAt || e.sys.createdAt}
        style={{margin: "10px 0"}}
        onClick={() => (
          sdk.navigator.openEntry(e.sys.id, { slideIn: { waitForClose: true } })
        )}
      />
        ))}

    </Flex>
  );
};

export default Home;

Navigator メソッドを利用して、ウインドウ内でContentfulページ間の遷移をトリガーできます。今回は記事IDを指定して記事編集ページへの遷移をさせています。

※外部リンクなどをaタグで書く場合、別タブで開かせる必要があります。

なおUIコンポーネントライブラリはContentfulのForma36を利用しています。

上記例では EntryCard というコンポーネントで、Contentful純正っぽい記事カードの表示方法を実現しています。

その他にも、基本的なページデザイン/レイアウトに必要なものは揃っているので、Contentful Appを実装する方はぜひ目を通してみてください。

https://f36.contentful.com/

Appのデプロイ

アプリをビルドします。

% npm run build

生成された dist 一式を、Contentfulに突っ込みます。

先ほど localhost を指定したアプリの設定画面に戻り、[Hosted by Contentful] にチェックを入れ、 dist ディレクトリをドラッグ&ドロップしてください。

scr_2023-09-19_1769

アプリのデプロイされたバージョンが残るため、わかりやすいコメントを残しておくこともできます。 scr_2023-09-19_1770

完成

再度、ContentfulのHomeにアクセスしてみましょう。

scr_2023-09-19_1771

自分の最新記事5件が表示されていますね。完成!

最後に

以上、Contentfulのフロントアプリの作成を通じて、Home画面をカスタマイズしてみました。

最近はバックエンドアプリ(イベントを条件にバックエンドで処理を行わせるもの)も開発できるようになり、対応できるユースケースも増えたました。そのためか自分も最近1週間に1つのペースでアプリを作っており、中々ブログ記事が追いつかないのが悩み...

クラスメソッドではContentfulの契約のご相談、構築支援をしています。ご興味のある方はぜひ弊社までお問い合わせください。

参考資料