前回の更新から大分時間が経ってしまいましたが、今回はヘッドレスCMSで毎回問題になる、プレビュー環境についてです。
ステージングサイトのSSR設定
AstroをはじめとするSSGサイトとヘッドレスCMSを連携する際には、コンテンツのプレビューが課題となりがちです。過去にはプレビューのために全ページを再ビルドしていたこともあったのですが、ビルドの待ち時間に不満があるため、今回は再ビルド不要なSSRをステージング環境だけで設定することにしました。SSRはSSGに比べて表示速度がやや遅く、また、リクエストごとに費用が発生しますが、わずかなリクエストしかないステージング環境においては問題ありません。
SSR設定に関しては、Astroには環境ごとのアダプターが用意されておりマニュアル類も充実しています。本サイトで使用しているNetlifyの場合、マニュアルに従ってAdapterの設定をConfigに記述するだけで簡単に導入できました。環境変数を設定し、ステージング環境でのみSSRを有効にすれば完了です。
非公開記事の認証
SSRの設定は簡単でしたが、このままではステージングサイトで確認できるコンテンツはWordPressの公開済み記事に限られます。一時的にWP上で記事を公開状態にすれば確認はできますが(本番ビルドをしない限り公開サイトには反映されないとはいえ)、この方法は運用フローとして適切ではありません。
そこで、ステージングサーバーからのAPIリクエストに認証情報を付与することで、WordPressの非公開記事も取得できるようにしました。実装の手順は以下の通りです。
- WordPress の管理画面で管理者権限を持つユーザーのアプリケーションパスワードを作成し、ユーザー名と共に環境変数として保存
- 非公開記事を取得するには、APIリクエストのヘッダーに認証情報を付与します。本サイトで採用しているGraphQLの場合、この認証情報の設定方法は以下の通りです。なお、認証トークンはBase64エンコードが必要ですが、Node環境では
window.btoa
が使用できないため、独自のエンコード関数を実装する必要があります。
export const encodeBase64 = (data: string) => {
return Buffer.from(data).toString("base64");
};
export const gqlClient = new GraphQLClient(URL_API, {
headers: {
Authorization: `Basic ${encodeBase64(WP_USER + ":" + WP_PASS)}`,
},
});
- あとは各リクエストに追加のステータスを指定するだけです。ちなみに、WPGraphQLでは複数のステータスを指定する場合の記述が特殊で
where: { stati: [PRIVATE, PUBLISH] }
と記述します。このstati
はWPGraphQL独自の用語らしく見つけるまでに少し苦労しました。また、非公開の投稿は未認証の場合は単に取得されないだけなので、公開サイト用のビルドで認証を行わなければ、同じクエリを使い回しても問題ありません。
プレビューURLの変更
WordPressの管理画面に表示される記事URLは、WordPressの設置サーバーに基づいたURLとなるため、公開URLやステージングURLとは異なります。このままではプレビューボタンを押しても意図したページが表示されないので、WordPressのフックを使って書き換えていきます。
preview_post_link
クラシックエディタ内のプレビューボタンの書き換え。純粋にstringを書き換えるだけなので単純。get_sample_permalink_html
クラシックエディタ内のパーマリンク欄の書き換え。HTML String を書き換える必要があるので、HTMLの構造を変更しないように注意が必要。rest_prepare_post
ブロックエディタからアクセスするREST APIに対する書き換え。リンク関連では、$response->data["link"]
がプレビュー用のリンク、$response->data["permalink_template"]
がSlug設定用のリンクラベルとなります。
まとめ
ヘッドレスCMSとしてのWordPressはもともとの設計思想と異なるところが多々あるため、そのままだと使いづらい部分も多いのですが、ここまで作業することでようやく使いやすさが出てきました。他にも改善点すべき点は多々あるので、それはまた別の機会にでも書くことにします。