WordPressをヘッドレスCMSにしてNext.jsでブログを作成する方法とエラー対処法

最近はReactをベースにしたフレームワーク、Next.jsをいじっております。今回はWordPressに登録した投稿をNext.jsで表示させてみようと思います!

↑私が10年以上利用している会計ソフト!

ヘッドレスCMSとは?

ヘッドレスCMSはコンテンツの管理のみをするCMS(=Content Management System)のこと。例えばWordPressではコンテンツの作成から表示までを行えますが、ヘッドレスCMSではコンテンツの表示は別の方法で行います。ここではNext.jsを使ってみます。

ヘッドレスCMSを使うメリット

表示部分を別途用意することになんのメリットがあるのでしょうか?ざっくりと以下の3点が挙げられるかなと思います:

  • 表示速度の改善
  • セキュリティの向上
  • 管理しやすい

通常のWordPressではアクセスがあるたびにデータを取得して表示しますが、Next.jsではあらかじめデータを取得して用意しているので、あとはリクエストがあれば表示するだけ、という状態にできます。そのためページの表示速度が上がります。

また、WordPressは表示部分と管理部分がセットになっているので、管理ページへのアクセスがしやすくなっています。example.com というサイトの管理ページは example.com/wp-admin ですよね。もちろんパスワードでロックされているものの、悪意のあるユーザーがなんらかの方法で突破してしまう可能性だってあります。

これは管理するページと表示するページを分離することで防げます。ドメインも別のものを用意して、管理する方のURLを隠せば、侵入されるリスクも軽減されるでしょう。

ヘッドレスCMSを使うデメリット

逆にデメリットはなんでしょうか?

  • 開発に手間がかかる
  • WordPressのテーマ、プラグイン、機能は使えない

一旦開発してしまえばいいところ満載なヘッドレスCMSですが、開発段階でかなりの時間がかかりそうです。WordPressのみだったら利用できたテーマもプラグインもショートコードなどの便利な標準機能もすべて使えなくなります。これまではクリックするだけできれいなデザインになったり、便利な機能が使えたはずなのに、それらは一から作っていくのです…。

WordPressをヘッドレスCMSにしてNext.jsでブログを作成する手順

メリット・デメリットを理解した上で、WordPressは記事の管理専用、Next.jsは表示専用にしてブログを作成する手順を見ていきましょう。Next.jsの公式サイトで手順デモが公開されていますよ!

1. Next.jsのプロジェクトを作成

まずはプロジェクトを作成しましょう。ターミナルで任意のフォルダーに移動後、以下のいずれかのコマンドを入力。

npmの場合

npx create-next-app --example cms-wordpress cms-wordpress-app

yarnの場合

yarn create next-app --example cms-wordpress cms-wordpress-app

pnpmの場合

pnpm create next-app --example cms-wordpress cms-wordpress-app

2. WPGraphQLプラグインをインストール

次はWordPress側の作業です。WordPressのデータを取得するために、GraphQLというAPIのためのクエリー言語を利用します。GraphQLを使えば必要な時に必要なデータを呼び出し、扱えるようになります。管理画面にログイン後、WPGraphQLというプラグインをインストールし、有効化しましょう。

管理画面のGraphQL → GraphiQL IDEのページでは3つのパーツに別れたページが表示されます。一番左の「Query Composer」パネルが開いていない場合は、画面上部の「Query Composer」ボタンをクリックしましょう。このQuery Composerには扱えるデータが階層構造で表示されています。必要なデータにチェックを入れるとクエリーが構築され、実行ボタンをクリックすると取得できるデータが右側に表示されます。

3. .env.local ファイルを作成

プロジェクトフォルダーの第一階層に .env.local というファイルを新規作成し、エンドポイントと呼ばれるAPIにアクセスするためのURIを指定します。これはWPGraphQLプラグインの設定画面に表示されています。

WORDPRESS_API_URL=https://example.com/graphql

4. 確認

あとは

npm install

で、動作させるための必要なパッケージをインストールして、

npm run dev

で画面を表示してみましょう。

(yarnの場合は yarn installyarn dev

http://localhost:3000/ にアクセスし、うまくいけばこんな感じのテンプレートにWordPressで用意しておいたコンテンツが入っているはずです!

だがエラーまみれ!!!

手順にそって作業したはずなのに、エラーだらけで全然表示されない!なんて事態に陥りましたよ…!ひとつひとつ英語サイトで調べながらなんとかエラーを駆逐してやりました。日本語だとあまり情報がなかったので、備忘録がてら残しておきますね。

Failed to fetch API

ホームページを表示しようとするとまず出てきたのがこのエラー。サンプルのコードだとデータを取得するクエリーの階層が少し違っているようです。クエリーは上記GraphiQL IDEでも確認できるので、使い方に慣れておくといいですね!具体的な修正箇所は lib/api.jsfeaturedImageauthor 部分です。これらを node で囲んであげましょう。

エラー箇所

query AllPosts {
      posts(first: 20, where: { orderby: { field: DATE, order: DESC } }) {
        edges {
          node {
            title
            excerpt
            slug
            date
            featuredImage {
              sourceUrl
            }
            author {
              name
              firstName
              lastName
              avatar {
                url
              }
            }
          }
        }
      }
    }

解決策

query AllPosts {
      posts(first: 20, where: { orderby: { field: DATE, order: DESC } }) {
        edges {
          node {
            title
            excerpt
            slug
            date
            featuredImage {
              node {
                sourceUrl
              }
            }
            author {
              node {
                name
                firstName
                lastName
                avatar {
                  url
                }
              }
            }
          }
        }
      }
    }

上記でホームのエラーはなくなりましたが、個別ページに移動するとまた同じエラーがでたので、同じく lib/api.js の以下の箇所も node で囲みます。

エラー箇所

featuredImage {
  sourceUrl
}
author {
  ...AuthorFields
}

解決策

featuredImage {
  node {
    sourceUrl
  }
}
author {
  node {
    ...AuthorFields
  }
}

Image is missing required “src” property.

アイキャッチ画像があるページでこんなエラーがでたら、画像のパスがうまく取得できていないってことです。 conponents/cover-image.jsnode を追加します。

エラー箇所

src={coverImage?.sourceUrl}

解決策

src={coverImage?.node.sourceUrl}

Error: Invalid src prop (example.jpg) on next/image, hostname “example.com” is not configured under images in your next.config.js

example.com としている箇所はヘッドレスCMSとして利用しているWordPressのドメインです。これは、next.config.js ファイルでドメインの設定を追加すればOK。

エラー箇所

module.exports = {
  images: {
    domains: [
      // "[yourapp].wpengine.com" (Update this to be your WordPress application name in order to load images connected to your posts)
      'secure.gravatar.com',
    ],
  },
}

解決策

module.exports = {
  images: {
    domains: [
      // "[yourapp].wpengine.com" (Update this to be your WordPress application name in order to load images connected to your posts)
      'secure.gravatar.com',
      'example.com',
    ],
  },
}

そして一度ターミナル止めて再度 npm run dev すると解消されていました。

TypeError: Cannot read properties of undefined (reading ‘url’)

執筆者の画像があるページで出てきたエラー。前述と同じく、components/avatar.js の該当箇所に node を追加で解消しました。

エラー箇所

src={author.avatar.url}

解決策

src={author.node.avatar.url}

私はひとまずこれで表示できましたが、まだまだなんらかのエラーに遭遇するかもしれません。。その時はまた共有します!

シェアする

ニュースレター

Web制作の最新情報やWebクリエイターボックスからのお知らせ、中の人の近況等を定期的にお送りいたします。 ぜひご登録ください!もちろん無料です! :)