ブログ

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';
}

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

今回は以上になります。

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

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

アーカイブ

新しいサイト制作や、既存サイトの運用に関するお困りごとなどございましたらご依頼、ご相談ください。

ビジネスやサービスに最適なウェブ制作、デザインをおこなっている株式会社ナナサンの会社案内をダウンロードいただけます。

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