💬

Payloadでグローバルを定義してフロント画面に表示する

に公開

はじめに

Payloadのグローバルとは、単一のレコードのみを登録できるデータモデルです。
Webサイトでいうと全ページに共通で表示するヘッダーメニューやフッターメニュー、緊急のお知らせエリアなどが該当します。

この記事では、シンプルな「緊急のお知らせ」グローバルを定義してフロント画面に表示するまでの手順を紹介します。

前提

  • フロントエンドの実装はNext.js App Routerで行います
  • フロントエンドの実装ではTailwind CSSを使用しています
  • 管理画面のサポート言語に日本語と英語を設定しています

管理画面の言語設定については、下記の記事をご参照ください。

https://zenn.dev/ksk1kd/articles/b69038ec67f799

緊急のお知らせグローバルの定義追加

Payloadでは、すべての設定をpayload.config.tsで行いますが、設定が増えてくるとファイルが肥大化するため、グローバルの定義はファイルを分割しpayload.config.tsからインポートすることが推奨されています。

グローバル定義ファイルの作成

まずは、src/EmergencyNotice/config.tsを作成し、下記の「緊急のお知らせ」グローバルの定義を記述します。

src/EmergencyNotice/config.ts
import type { GlobalConfig } from 'payload'

export const EmergencyNotice: GlobalConfig = {
  slug: 'emergency-notice',
  label: {
    en: 'Emergency Notice',
    ja: '緊急のお知らせ',
  },
  fields: [
    {
      name: 'items',
      label: {
        en: 'Items',
        ja: 'アイテム',
      },
      type: 'array',
      fields: [
        {
          name: 'title',
          label: {
            en: 'Title',
            ja: 'タイトル',
          },
          type: 'text',
          required: true,
        },
      ],
      maxRows: 10,
    },
  ],
}

上記の定義内容について、主要な部分のみ解説したいと思います。

フィールド

「アイテム」という名称の配列フィールドを定義し、その子要素として「タイトル」フィールドを定義しています。配列構造にすることで複数のタイトルを登録できるようにしています。

ラベル

グローバルのラベルやフィールドのラベルには、日本語用と英語用のラベルを設定しています。これは、管理画面のサポート言語に日本語と英語を設定しているためです。ご自身の環境の管理画面サポート言語設定に則して適宜編集してください。

グローバル定義ファイルのインポート

作成したグローバル定義ファイルをsrc/payload.config.tsからインポートします。

src/payload.config.tsに下記を追加します。

src/payload.config.ts
import { EmergencyNotice } from './EmergencyNotice/config'

export default buildConfig({
  // ...
  // すでにglobalsキーがある場合は配列の中に「EmergencyNotice」を追加します
  // Payload管理画面では配列の要素順で表示されるため、適切な位置に挿入します
  // e.g. globals: [Header, Footer, EmergencyNotice],
  globals: [EmergencyNotice],
})

これでグローバルの定義追加は完了です。

サンプルデータの登録

設定が完了し管理画面にアクセスすると、左メニューに「Emergency Notice」が追加されたことを確認できると思います。管理画面の言語設定を日本語にしていると「緊急のお知らせ」と表示されます。

後ほどフロント画面を実装するため、サンプルデータとして複数のタイトルを登録しておきます。
編集画面は、先ほどのグローバル定義により下記キャプチャのようになります。

緊急のお知らせの編集画面

緊急のお知らせエリアの実装

次に緊急のお知らせエリアをコンポーネントとして実装します。

src/EmergencyNotice/Component.tsxを作成して、下記のコードを記述します。
このコードはパフォーマンスを考慮していませんので、その点はご注意ください。

src/EmergencyNotice/Component.tsx
import configPromise from '@payload-config'
import { getPayload } from 'payload'

export async function EmergencyNotice() {
  const payload = await getPayload({ config: configPromise })

  const emergencyNotice = await payload.findGlobal({
    slug: 'emergency-notice',
  })

  const items = emergencyNotice?.items || []

  if (items.length === 0) return

  return (
    <ul className="flex flex-col bg-red-500">
      {items.map((item) => (
        <li className="px-4 py-2" key={item.id}>
          {item.title}
        </li>
      ))}
    </ul>
  )
}

レイアウトファイルから上記のコンポーネントをインポートして、緊急のお知らせエリアがWebサイトの全ページで表示されるようにします。

src/app/(frontend)/layout.tsxに下記を追加します。
下記は例です。ご自身の環境に合わせて適切な位置に追記してください。

src/app/(frontend)/layout.tsx
import { EmergencyNotice } from '@/EmergencyNotice/Component'

// ...
  return (
    // ...
    <EmergencyNotice />
    // ...
  )
// ...

アクセスしてみると、下記キャプチャのように全ページに緊急のお知らせエリアが表示されていることを確認できます。

緊急のお知らせエリアのサンプル
※デザインはご自身の環境に依存します

まとめ

この記事では、「緊急のお知らせ」グローバルを定義してフロント画面に表示するまでの手順を紹介しました。「グローバル」という言葉だけではどのような機能がイメージし難いですが、この記事を通してグローバルとは何かを把握していただけたならば幸いです。

参考

https://payloadcms.com/docs/configuration/globals

https://payloadcms.com/docs/local-api/overview

Discussion