2025年05月30日
この記事では、プラグイン「WP GraphQL」を使ってヘッドレス化したWordPressと静的サイトジェネレーター「11ty」を使ってブログサイトを作成する手順を紹介します。
ヘッドレスCMSの運用は、SaaSであるmicroCMSやContentfulなどでの運用が多いかと思います。
ただ、よく使われているCMSで自前のレンタルサーバーで使えるヘッドレスCMSも条件によって使いどころがあるとは思います。
WordPressがヘッドレス化できることは知っていたのですが、試したことがなかったので今のポートフォリオサイト(11ty+Newt)のヘッドレスCMS部分の置き換え想定で簡単なサンプルを作ってみたので、記事にしておきます。
説明とかいいから、コードを見たいという方は、下記のGitHubのリポジトリを試してみてください。
先日、ポートフォリオサイトを11ty + Newtに置き換えたのですが、Newtのサービス終了が発表されました。
使い勝手もよかったので残念ですが、きっとNewtの中の人も無念だと思うので、そこはしょうがないのですが、乗り換え先を検討することになりました。
選択してとしては、
最有力は1で、microCMSやContentfulへの乗り換えです。サーバーの面倒を見なくていいのが圧倒的にメリットがあります。
ただ、
2はCockpit CMSなどあるったり、3も最小構成ならありかなと思ったのですが、
4に関しては、できるのは知っていたのですが、
とはいえ、一番よく知っているCMSでヘッドレスCMSが作れるのは、常用はしないにしろ知っておいて損はないなと思い、サンプルを作成してみることにしました。
WordPressのAPIは標準では、Restが使われています。
WordPressのデータ構造を生かすならそのままでもよかったのですが、ヘッドレスCMSで使う場合、取得データを自由に調整しやすいGraphQLの方が向いているかなと思ったのとWP GraphQLで簡単にGrapQLに出来そうだったので、こちらのプラグインもテストしておきたいと思い、GraphQLを採用しました。
WordPressのエディタの主流はブロックエディタです。
なので、
ここでは、以下の手順でWordPress(GraphQL) + 11tyのブログサイトを構築していきます。
まず、11tyプロジェクトを作成し、必要なパッケージをインストールします。
mkdir wp-11ty-blog
cd wp-11ty-blog
npm init -y
npm install @11ty/eleventy node-fetch dotenv
次にWordPressのセットアップをしていきます。
まずは、WordPressをインストールします。
今回はテストの為、Windows11上のLocalにインストールしました。
今回はGraphQLにしたいので、WPGraphQLを追加します。
また投稿タイプを取得するサンプルですが、カスタムフィールドやカスタム投稿を使う場合は別途追加してください。
※ カスタムフィールド、カスタム投稿に関する詳細はこの記事で紹介していないのでご注意ください。
また、テーマもAPIを取得することを考えれば何でもよいのですが、シンプルでスタイリングしやすいブロックエディタに対応しておくと、プレビューやブロックエディタの見た目の実際のサイトの見た目を寄せることがしやすいです。
そこで今回は、AstroでWordPressを爆速Headless化してみるという参考にした記事でも使われていた「Arkhe」テーマをインストールしました。
テスト用に記事を1件以上投稿しておきます。
今回はブロックエディタの見た目とそろえようと思うので、カラムブロックなども作って下記のようなダミー記事を作成しました。
上図 / WordPressの投稿のブロックエディタ画面
プロジェクトのルートディレクトリに.envファイルを作成し、WordPressの認証情報を設定します。
WP_GRAPHQL_ENDPOINT=あなたのWordPressのURL/graphql
// Localでやっている場合、LiveLinkでユーザー名とパスワードを要求される
WP_GRAPHQL_USER=あなたのLiveLinkのユーザー名
WP_GRAPHQL_PASS=あなたのLiveLinkのパスワード
今回は、Windows 11上のLocalでWordPressを動かし、11tyをWSL2環境で動かしていたので、LocalのLiveLink機能を使って外からでもAPIにアクセスできるようにしてテストしました。
なので、ユーザー名とパスワードの部分は各環境に合わせて調整してください。
_dataディレクトリを作成し、WordPressからデータを取得するスクリプトを作成します。
mkdir -p src/_data
touch src/_data/posts.js
// src/_data/posts.js
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
require("dotenv").config();
module.exports = async function () {
const query = { posts { nodes { title slug content date } } }
;
const basicAuth = Buffer.from(
${process.env.WP_GRAPHQL_USER}:${process.env.WP_GRAPHQL_PASS}
).toString("base64");
const res = await fetch(process.env.WP_GRAPHQL_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: Basic ${basicAuth}
,
},
body: JSON.stringify({ query }),
});
const json = await res.json();
if (!json.data || !json.data.posts) {
throw new Error("GraphQL APIからpostsデータが取得できませんでした");
}
// pagination のために配列を直接返す
return json.data.posts.nodes;
};
Nunjucksテンプレートを使用して、記事一覧ページと個別記事ページを作成します。
touch src/index.njk
mkdir src/posts
touch src/posts/post.njk
src/index.njk(一覧ページ)
<h1>
ブログ一覧
</h1>
<ul>
{% for post in posts %}
<li>
<a href="/posts/{{ post.slug }}/">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
src/posts/post.njkファイルで、個別記事ページのテンプレートを作成し、paginationを使って動的にページを生成します。
---
pagination:
data: posts
size: 1
alias: post
permalink: "posts/{{ post.slug }}/index.html"
---
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8"/>
<title>{{ post.title }}</title>
{# WordPress の CSS を読み込む #}
<link rel="stylesheet" href="https://spiffy-eggs.localsite.io/wp-includes/css/dist/block-library/style.min.css">
<link rel="stylesheet" href="https://spiffy-eggs.localsite.io/wp-content/themes/arkhe/dist/css/main.css">
</head>
<body>
<div class="l-content__body l-container">
<main id="main_content" class="l-main l-article">
<article class="l-main__body p-entry post-1 post type-post status-publish format-standard hentry category-uncategorized" data-postid="1">
<header class="p-entry__head">
<div class="p-entry__title c-pageTitle">
<h1 class="c-pageTitle__main">{{ post.title }}</h1>
</div>
</header>
<div class="c-postContent p-entry__content">
{{ post.content | safe }}
</div>
</article>
</main>
</div>
</body>
</html>
基本的には、読み込んだWordPressの投稿の記事の情報を出力しているだけですが、ブロックエディタの表示と対応させるために、WordPressのブロックパターンとテーマのCSSを読み込んでします。
上図 / 11tyのビルドした個別記事ページ
プロジェクトのルートに.eleventy.config.jsファイルを作成して、11tyの設定を行います。
今回は、ディレクトリの構造をしているだけです。
module.exports = function (eleventyConfig) {
// ディレクトリ構成の設定
return {
dir: {
input: "src",
output: "dist",
},
};
};
package.jsonにスクリプトを追加します。
"scripts": {
"start": "eleventy --serve",
"build": "eleventy"
}
開発サーバーを起動します。
npm start
これで、WordPressで管理しているコンテンツを11tyで静的サイトとして生成できるようになります。
ここまでのコードが下記のGitHubのリポジトリに公開しているので良かったら参考にしてみてください。
https://github.com/hanahana0201/wp-11ty-blog
実際に運用しようと思うと下記のことも検討していく必要があるかなと思います。
この記事では、WordPressと11tyで作るブログサイトの作り方を紹介してきました。
データの取得方法、Webhookや記事のプレビュー回りを思うとあえてWordPressを使わなくても良いかなという気はしますが、何だかんだ慣れているので、一度しっかりベースを作ればありなのかなという印象でした。
ただ手軽さはSaaSが勝るので、あえて使うかは悩ましいところです。
誰かの参考になれば幸いです。