Gatsby.jsは言わずと知れたReact製の静的サイトジェネレーターですが、ビルド時にページを生成するという性質ゆえに、microCMSのプレビュー機能を使うにはひと工夫必要だったので共有したいと思います。
この機能をご存知の方はコードの部分からご覧ください。
microCMSの記事プレビュー機能について
microCMSのプレビュー機能について少し説明しておくと、記事執筆画面で
公開ボタンの左にある画面プレビューを押した時に、執筆中の記事が実際にはどのように表示されるか確認できる機能です。仕組みとしては、
という感じです。
詳しくはhttps://microcms.io/blog/draftkey_and_preview/ に掲載されています。
### 何が問題でどうしたらいいのか?
この機能をGatsbyで使用する時、考えなければならないのは、Gatsby.jsの記事データは基本ビルド時に生成された物なので、
**「画面プレビュー」クリック時に送られてきたcontentId
とdraftKey
を基に記事データをリアルタイムに取得して、表示する仕組みを作らないといけない。**ということです。
## ということでコード
前置きはそのくらいにしてコードはこのようになりました。
import React, { useState, useEffect } from "react";
import { getSearchParams } from "gatsby-query-params";
//...その他コンポーネントなど
function previewPage() {
//microCMS側に設定するurlはhttps://xxxxxx.com/previewPage/?contentId={CONTENT_ID}&draftKey={DRAFT_KEY}みたいな感じ
const queryParams = getSearchParams();
//queryParamsには
//{contentId:"xxxx",
//draftKey:"xxxx"}
//というようなデータが入ります。
const contentId = queryParams.contentId;
const draftKey = queryParams.draftKey;
const [postData, setPostData] = useState(null);//最初、postDataにはnullが入ります。
useEffect(() => {
if (!postData) {
fetch(
`https://xxxxxxxxx.microcms.io/api/v1/blogs/${contentId}?draftKey=${draftKey}`,
{
headers: {
"X-API-KEY": "xxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxx",
},
}
)
.then((response) => {
if (response.ok) {
return response.json();
}
})
.then((json) => {
postData = setPostData(json);//ここで、postDataに取得したコンテンツが格納されます。
});
} else {
return function cleanup() {
console.log("done");
};
}
});
return (
<div
dangerouslySetInnerHTML={{
__html: postData ? postData.sentence : "",
}}
></div>
);
}
export default previewPage;
このようなページを作成することで、アクセスした時にurlクエリパラメータの情報を基にコンテンツをとってきてくれます。
以下、詳しく説明していきます。
API部分について
microCMSはPOSTとGETのAPI-KEYが違うのでGETのAPIが露出しても大して問題はないですが、なんとなく気持ちが悪いので、
X-API-KEY: "xxxxx-xxxx"としている部分とmicroCMSのurl部分は実際には環境変数に置き換えるのが望ましいです。環境変数の使い方に関してはこちらの記事の中でも説明しているので是非ご覧ください。
gatsby-query-params
について
2行目に登場するgatsby-query-params
はこちらです。
使用するにはターミナルでnpm i gatsby-query-params
してください。
コメントアウト部分にもありますが、getSearchParams
によって、urlクエリパラメータの情報をqueryParams
にオブジェクト形式で格納しています。
useState
useEffect
について
これらはReactのhookで、詳しい説明はこちらにあります。
useEffect
の中で、↑で取得したクエリパラメータを基にmicroCMSにデータを取得しにいき、取得できたら、それをpostData
に格納しています。
###responce.ok
について
これがないとmicroCMSのレスポンスが404の時(useStateがnullの間)返ってくる空文字列""
を処理しようとしてしまい、jsonオブジェクトでないのでエラーが出てしまいます。
レンダリング部分について
return()
内のpostData ? postData.sentence : ''
としている部分で、postDataに↑でとってきた記事データが格納されたら、それが表示されるようになっています。postData.sentence
と書いていますが、sentence
の部分はmicroCMSで定義した表示したいデータのフィールドIDが入ります。レンダリング部分は他の記事ページのレイアウトに合わせて、煮るなり焼くなりしてください!
##まとめ
サイトを見にきた人が、/今回作ったページ
と打つとアクセスできてしまいますが、contentsIdとdraftKeyがないので何も表示されないですし、一応は問題ないと思います。
色々と改善の余地はありそうですが、とりあえずこれで投稿前の記事をプレビューで確認できるので、是非活用してみてください!