microCMS

microCMSでWebアプリケーションのイベントバナーを実装する

りゅーそう

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

こんにちは。野崎です。

先日、開催しました「microCMS Online Meetup」の際にイベントバナーが管理画面上部に表示されたのにお気づきでしたでしょうか?
実はこれもmicroCMSを使用してイベント情報を管理しています。
この記事では、microCMSのようなSPAアプリケーションでイベントバナーを表示させる方法を紹介します。

実装するもの

以下のような画面上部のバナーを表示・管理する仕組みを実装します。

管理画面(サービス内)に表示させるものなので以下のような仕様となっています。

  • 何個も表示すると操作の邪魔になるので、一個のみの表示とする
  • イベント情報が必要ないユーザーもいるので「閉じる」ボタンでバナーを消せるようにする
  • Cookieを用いて、実装コストを下げる。
  • イベント情報を表示するたびにCookieを保存するとパフォーマンスにも影響するので、イベント更新のたびにCookieを削除する


実装方法

microCMSで行っている実装方法を紹介します。

使用技術

microCMSではフロントエンドの開発にReactを使用しているので、その前提での解説になります。
microCMSのデータ取得にはReact Queryを使用しています。
取得するmicroCMSのAPIスキーマは以下のようなシンプルなものとなっています。

前章でも述べたとおり、イベントバナーの表示ロジックにはCookieを用いてイベントバナーの出しわけを行っています。

管理するためのReact Hooksを作成する

React Hooksを用いてイベントバナーの表示ロジックを実装します。
コンポーネント側に実装するのではなく、Hooks内に処理を実装することで、コンポーネント側ではmicroCMSの値を意識せずに実装をすることができます。
Hooksの全容を載せます(一部表示をサンプル用に省略・変更しています)。

import { useCallback, useState, useEffect } from 'react';
import { useQuery } from 'react-query';
import { useCookies } from 'react-cookie';
import { client } from "../lib/microcmsClinet"
import dayjs from 'dayjs';

export const useInfo = () => {
  const getInfoQuery = useQuery(
    ['microcmsInfo'],
    async () => {
      return await client.get({
        endpoint: 'info',
        queries: { fields: 'id,title,link,publishedAt' },
      });
    },
    { staleTime: Infinity }
  );

  const { data: info, isLoading: isInfoLoading } = getInfoQuery;

  const [cookies, setCookie, removeCookie] = useCookies([
    `sample#cookie`,
  ]);
  const [isInfoOpen, setInfoOpen] = useState<boolean>(
    !cookies[`sample#cookie`]
  );

  const latestContentPublishedAt = info?.contents?.[0]?.publishedAt;
  useEffect(() => {
    if (latestContentPublishedAt > cookies[`sample#cookie`]) {
      removeCookie(`sample#cookie`, {
        path: '/',
      });
      setInfoOpen(true);
    }
  }, [cookies, latestContentPublishedAt, removeCookie]);


  const closeInfo = useCallback(
    (e) => {
      setCookie(`sample#cookie`, new Date().toISOString(), {
        path: '/',
        expires: dayjs().add(20, 'year').toDate(),
      });
      setInfoOpen(false);
      e.preventDefault();
    },
    [setCookie]
  );


  return {
  // 最新の一件のみを返す
    info: info?.contents?.[0],
    isInfoOpen,
    closeInfo,
    isInfoLoading,
  };
};


処理の詳細を解説します。
まずはReact QueryでmicroCMSのAPIを叩いてイベントバナーの情報を取得します。
ポイントはReact QueryのオプションstaleTime: Infinity を設定していることです。
キャッシュを保持することにより余計な再取得を防ぐことができます。
またmicroCMSのクエリで fields を指定してクエリを絞り込むことで、使用するデータのみ取得することができます。。

  const getInfoQuery = useQuery(
    ['microcmsInfo'],
    async () => {
      return await client.get({
        endpoint: 'info',
        queries: { fields: 'id,title,link,publishedAt' },
      });
    },
    { staleTime: Infinity }
  );

  const { data: info, isLoading: isInfoLoading } = getInfoQuery;



次にイベントバーの「×」ボタンを押したときにイベントバナーを閉じる実装です。
閉じるボタンを押したときにCookieを保存して、一度閉じたバナーは表示されない仕組みを実装します。
Cookieを扱うのに、react-cookieを使用しています。
https://www.npmjs.com/package/react-cookie

  const [cookies, setCookie, removeCookie] = useCookies([
    `sample#cookie`,
  ]);
  
// Cookieが保存されていない場合はイベントバナーを表示する状態
  const [isInfoOpen, setInfoOpen] = useState<boolean>(
    !cookies[`sample#cookie`]
  );

  // 省略
  
// 閉じるボタンを押したときにCookieをセットして非表示にする
  const closeInfo = useCallback(
    (e) => {
      setCookie(`sample#cookie`, new Date().toISOString(), {
        path: '/',
        expires: dayjs().add(20, 'year').toDate(),
      });
      setInfoOpen(false);
      e.preventDefault();
    },
    [setCookie]
  );


最新のコンテンツ情報が追加されたときに、過去に保存されたCookieを削除します。
Cookieに閉じるボタンをクリックした日時を保存しているので、それと最新コンテンツの日時と比較して削除を行っています。

  const latestContentPublishedAt = info?.contents?.[0]?.publishedAt;
  useEffect(() => {
    if (latestContentPublishedAt > cookies[`sample#cookie`]) {
      removeCookie(`sample#cookie`, {
        path: '/',
      });
      setInfoOpen(true);
    }
  }, [cookies, latestContentPublishedAt, removeCookie]);


コンポーネント側でロジックを使用してバナーを表示させる

コンポーネント内で上記のロジックを利用します。実装の一部を掲載します。
Hooksベースで実装を行っているので、簡単に値を扱うことができます。
microCMSでは、Notification コンポーネントを作ってそれを表示するようにしています。

  const { info, isInfoOpen, closeInfo, isInfoLoading } = useInfo();

  return (
    <div>
      {info &&
        isInfoOpen &&
        isInfoLoading === false && (
          <a href={info.link} target="_blank" rel="noreferrer">
            <Notification  text={info.title}  close={closeInfo}/>
          </a>
       )}
    </div>
  )


最後に

microCMSでイベントバナーを管理することで、バナーを入稿するときの実装コストが0になりました。
実際にmicroCMSでもこの仕組みを採用することで非エンジニアの方がバナーを更新する運用を行っています。

ぜひお試しください。

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

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

microCMSを無料で始める

microCMSについてお問い合わせ

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

お問い合わせ

microCMS公式アカウント

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

  • X
  • Discord
  • github

ABOUT ME

りゅーそう
1994年生まれ。 前職は高校地理歴史科教員。2021/9〜microCMS入社。React/TypeScriptが好きです。