更新日
WordPressをヘッドレスCMSにしてNext.jsでブログを作成する方法とエラー対処法
最近はReactをベースにしたフレームワーク、Next.jsをいじっております。今回はWordPressに登録した投稿をNext.jsで表示させてみようと思います!
ヘッドレス 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 install
+ yarn dev
)
http://localhost:3000/ にアクセスし、うまくいけばこんな感じのテンプレートに WordPress で用意しておいたコンテンツが入っているはずです!
だがエラーまみれ!!!
手順にそって作業したはずなのに、エラーだらけで全然表示されない!なんて事態に陥りましたよ…!ひとつひとつ英語サイトで調べながらなんとかエラーを駆逐してやりました。日本語だとあまり情報がなかったので、備忘録がてら残しておきますね。
Failed to fetch API
ホームページを表示しようとするとまず出てきたのがこのエラー。サンプルのコードだとデータを取得するクエリーの階層が少し違っているようです。クエリーは上記 GraphiQL IDE でも確認できるので、使い方に慣れておくといいですね!具体的な修正箇所は lib/api.js の featuredImage
や author
部分です。これらを 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.js で node
を追加します。
エラー箇所
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}
私はひとまずこれで表示できましたが、まだまだなんらかのエラーに遭遇するかもしれません。。その時はまた共有します!