ブログ

WordPressヘッドレス化(next.js)

2024.03.04 : Yamamoto Naoki
Frontend

前回までのあらすじ

WP GraphQLをインストールし、queryと吐き出されるデータを確認しました。

今回は以下を参考にして進めていきます。

ただし、こちらのサイトはREST APIなのでgraphQLに変更します。

https://kinsta.com/blog/headless-wordpress-next-js/

Next.jsのインストール

フロントをnext.jsを使って表示させるためインストールします。

上記の参考サイトを参考にインストール作業を行っています。

※最終的には、現行サイトに合わせてCSSを導入していきますが、今回はテスト的にnext.jsでgraphQL のデータを取得して表示させることを目的として進めていきます。

npx create-next-app@latest nextjs-wp-demo(お好きな名前で)

各設定は以下で行いました。

✔ Would you like to use TypeScript? … No / Yes

✔ Would you like to use ESLint? … No / Yes

✔ Would you like to use Tailwind CSS? … No / Yes

✔ Would you like to use `src/` directory? … No / Yes

✔ Would you like to use App Router? (recommended) … No / Yes

✔ Would you like to customize the default import alias (@/*)? … No / Yes

✔ What import alias would you like configured? … @/*

※Tailwind CSSは最終的には使いませんが、簡易的に表示させるためにインストールしておきます。

参考サイトに書いているとおりにgitのリポジトリからデータを落として、npm run devでローカルで確認します。

http://localhost:3000/ で以下のようなページが表示されるはずです。

このままでは、データを読み込んで表示はされないので、graphQLを使ってデータを読み込むためのコードを追加修正していきます。

まず、Appディレクトリー内に.env.localファイルを作成し、以下を記述

WORDPRESS_API_URL=‘wordpressで設定したgraphqlのURL’

続いて、app>page.js(これがトップページになります)を開きます。先にコードを記します。

1行目の「import Link from ‘next/link’;」

の下に、以下を追加

async function getPosts() {
    const query = `
        query MyQuery2 {
            blogs(first: 3) {
                edges {
                    node {
                        blogId
                        date
                        title
                        categories {
                            edges {
                                node {
                                    name
                                }
                            }
                        }
                        writer {
                            nodes {
                                name
                            }
                        }
                        featuredImage {
                            node {
                                sourceUrl(size: LARGE)
                            }
                        }
                    }
                }
            }
        }
    `;

const response = await fetch(process.env.WORDPRESS_API_URL, {
        body: JSON.stringify({ query }),
        headers: {
            'Content-Type': 'application/json',
        },
        method: 'POST',
        next: { revalidate: 10 },
    })
        .then((res) => {
            if (!res.ok) {
                throw new Error('HTTPエラー ' + res.status);
            }
            return res.json();
        })
        .then((json) => {
            return json.data.blogs.edges;
        })
        .catch((error) => {
            console.error('エラー: ' + error.message);
        });
    return response;
}

</Link>の下に以下を追加

<h2>ブログ読み込み</h2>
<div className="posts">
	{posts.map((post) => {
		let writer;
		let category;
		let imageUrl;
		if (post.node.featuredImage) {
			imageUrl = post.node.featuredImage.node.sourceUrl;
		} else {
			imageUrl = '/img/common/noimg.png';
		}
		post.node.writer.nodes.map((writerData) => {
			writer = writerData.name;
		});
		post.node.categories.edges.map((cat) => {
			category = cat.node.name;
		});
		return (
			<Link href={`/blog/${post.node.blogId}`} className="post" key={post.node.blogId}>
				<div>{post.node.title}</div>
				<div>{post.node.date}</div>
				<div>{category}</div>
				<div>{writer}</div>
				<img src={imageUrl} width={200} />
			</Link>
		);
	})}
</div>

最後にスタイルを修正します。

global.cssの110行目~147行あたりの以下のclassの「.blog-page 」を削除

以下の「.blog-page 」を削除

.blog-page .posts

.blog-page .post

.blog-page .post .post-img

.blog-page .post h3

.blog-page .post p

.blog-page 」を削除後がこちら

.posts

.post

.post .post-img

.post h3

.post p

これで、最新のブログ記事3件が以下のようになったと思います。

http://localhost:3000/ で以下のようなページが表示されるはずです。

では、ざっくり説明します。

query MyQuery2

はじめのquery MyQuery2 はwprdpessで作ったgraphQLのqueryをそのまま貼ります。

blogs(first: 3)のfirst: 3ははじめの3件取得になります。

const response

次のconst response = await fetch(process.env.WORDPRESS_API_URL, {

は、fetchを使ってAPIからデータを読み込んでjsonを返しています。

process.env.WORDPRESS_API_URLは、.env.localで設定したものになります。

ブログ読み込み

</Link>の下に追加した部分は、console.logで、出力すると以下のJSONデータを持っています。

[
  {
    node: {
      blogId: 1798,
      date: '2023-11-01T11:55:00',
      title: 'ナナサンホームページリニューアルの裏側',
      categories: [Object],
      writer: [Object],
      featuredImage: [Object]
    }
  },
  {
    node: {
      blogId: 1784,
      date: '2023-10-24T16:30:36',
      title: 'APNGでアニメーション画像を作ろう!',
      categories: [Object],
      writer: [Object],
      featuredImage: null
    }
  },
  {
    node: {
      blogId: 1773,
      date: '2023-10-19T09:00:56',
      title: '「確認漏れ」の減らし方',
      categories: [Object],
      writer: [Object],
      featuredImage: [Object]
    }
  }
]

このJSONデータをmap関数で各記事データ毎にを表示する部分が以下です。

return (
	<Link href={`/blog/${post.node.blogId}`} className="post" key={post.node.blogId}>
		<div>{post.node.title}</div>
		<div>{post.node.date}</div>
		<div>{category}</div>
		<div>{writer}</div>
		<img src={imageUrl} width={200} />
	</Link>
);

writer、category、imageUrlは、取得したデータ内で更に階層が深かったり、配列だったりするのでそれを取り出すためのmapなど使って取得しています。

if (post.node.featuredImage) {
	imageUrl = post.node.featuredImage.node.sourceUrl;
} else {
	imageUrl = '/img/common/noimg.png';
}

上記は、アイキャッチ画像がない場合は、準備している共通画像を表示するように指定しています。

今回は以上になります。

とりあえず、ブログ記事を指定数表示するようにしてみました。

弊社のトップページには、制作実績、お知らせなど複数投稿記事がありますので、次回は複数表示する場合を試してみたいと思います。

アーカイブ

資料ダウンロード 制作依頼・ご相談
イメージ:制作依頼・ご相談
イメージ:制作依頼・ご相談