microCMSには、ステータスが「下書き中」になっている記事を取得できる機能が用意されています。
今回は、その機能を利用してブログのプレビューページを作りました。

モチベーション

  • 執筆中の記事の見栄えを公開前に確認したい
  • このブログはJamstackな構成でできているので、記事公開 → デプロイ → ページ生成 されるまで実際の表示が確認できず、リスキー
  • デプロイすることなくプレビュー可能な仕組みが必要


大まかな方針

プレビュー用のページをGatsbyのsrc/pages配下に用意しておき、クエリパラメータで指定されたcontentId, draftIdに一致するコンテンツをmicroCMSからクライアントサイドで取得します。
取得した記事のデータをReact コンポーネントに渡してクライアントサイドでレンダリングします。

準備

microCMSの管理画面から、プレビューボタン押下時の遷移先URLを設定しておきます。

上記画像のblogPostPreviewにあたる文字列が、Gatsbyのプレビュー用ページのファイル名と一致することになります。

クエリパラメータからcontentIdとdraftIdを取得する必要があるため、クエリパラメータから値を取得するためのパッケージを追加しておきます。
yarn add gatsby-query-params

実装

プレビューページの追加

src/pages配下にblogPostPreview.jsというページファイルを追加しました。今回は、ブログ投稿専用のプレビューページであることを明示したかったのでこのようなファイル名にしました。

下書き状態のコンテンツを取得する

gatsby-query-paramsからgetSearchParamsをimportし、contentId, draftIdを取得します。
contentId, draftIdを使って、下書き状態のコンテンツを取得するためのクエリを組み立ててfetchします。

const { contentId, draftKey } = getSearchParams()
    const [postData, setPostData] = useState(null)
  
    useEffect(() => {
      if (!contentId || !draftKey) return
      fetch(
        `https://xxxxxxxxxxxxxxx.microcms.io/api/v1/blog/${contentId}?draftKey=${draftKey}`,
        {
          headers: {
            "X-API-KEY": "xxxxxxxxxxxxxxxxxxxxxxxx",
          },
        }
      )
        .then(response => {
          if (response.ok) {
            return response.json()
          }
        })
        .then(json => {
          if (json) {
            setPostData(json)
          }
        })
    }, [contentId, draftKey])

APIキーがむき出しになってしまいますが、個人開発の用途であること・とりあえず早くプレビュー機能を使える状態にしたかったためこのままでいきます。
getの操作でした使用されないAPIキーなので、フロントエンドで見える状態になっていても特に問題ないかなと思います。
気になる方は、microCMSの公式ブログにNetlify Functionsを使ってサーバサイドで下書き状態の記事のデータを取得する実装が紹介されているのでこちらを参考にすると良さそうです。
Nuxt.jsでの実装例が掲載されてますが、使っているフレームワークによらず参考にできそうな実装です。
microCMSとNuxtでプレビュー画面を作成する

レンダリング

データが取得できたらもう殆ど完成です。最後は記事詳細ページですでに使用されているPostHeader, PostBodyコンポーネントに記事のデータをpropsで渡してあげるだけです。
ここまでの作業でできたファイルは以下となります。(jsx のsyntax highlightが壊れてる問題がまだ解決できてなくてめちゃくちゃ不便)
https://github.com/EringiV3/devBlog/blob/master/src/pages/blogPostPreview.js

記事の公開日時のデータについて、SSGするときはgraphqlのクエリでフォーマット指定してリクエストを行っているため自分で公開日時のフォーマットは行っていません。
ただ、プレビューではgraphqlは使わずにfetchで取得しているのでフォーマットの指定はできません。そのためフォーマットされていないプレーンな状態の日時文字列をそのまま表示しています。
(プレビューだから対応する気が起きなかった)



以上でプレビュー機能の実装が一通り完了したので、microCMSのプレビューボタンを押してみてプレビューができてるかを確認します。

「画面プレビュー」ボタンを押して...

プレビューページ用のURLで下書き状態の記事のプレビューができました!!
これで完成です!

まとめ

microCMSのプレビュー画面機能を使用して、Gatsby上に動的なプレビューページを作りました。
プレビュー機能はブログには必須と言えるレベルの機能だと思うので、自作ブログを構築して早い段階で用意できて安心です。