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