Ryota Kondo

Ryota Kondo

2023/04/24

microCMS + Astro|ハイブリッドレンダリングを用いた画面プレビュー実装方法

今回は、Astro 2.0で追加されたハイブリッドレンダリングを用いて、microCMSの管理画面からプレビューできるようにする方法について説明します。

Astroのハイブリッドレンダリングは、サーバーサイドレンダリング(SSR)と静的サイト生成(SSG)の様なビルド時の静的レンダリングとをページ毎に変えることができます。これを利用してサイトで公開するページは静的レンダリングのまま、microCMSからプレビューするページのみSSRとなるようにします。

プレビューページのみSSRにするメリットは下の点が挙げられます。これから説明する実装の手間を考慮しても対応する価値はあるかと思いますので、参考となれば幸いです。

【メリット】

  • 一般に公開するページは静的レンダリングのまま、ビルド不要でプレビューが可能
  • プレビューページにAstroコンポーネントが使用可能
  • 環境変数に設定したmicroCMSのサービスドメイン名、APIキーをクライアントサイドに公開しなくてよい

注意点

この方法を実施するために、デプロイ先のホスティングサービスに合わせたアダプターをAstroにインストールする必要があります。現時点(2023/4/23)では下のサービスのみアダプターが用意されています。

  • Cloudflare
  • Deno
  • Netlify
  • Node.js
  • Vercel

将来的には追加するとのことですので、最新情報はこちらのAstro公式ドキュメントをご確認ください。

また、Cloudflareのアダプターは@astrojs/imageを現時点(2023/4/23)でサポートしていませんのでご注意ください。最新情報についてはこちらもAstro公式ドキュメントをご確認ください。

実装方法

ハイブリッドレンダリングの有効化

まずはastro.config.mjsファイルを変更して、デプロイ先でのハイブリッドレンダリングを有効にします。下の様にoutput: 'hybrid'を追加してください。静的レンダリングをデフォルトとしたハイブリッドレンダリングが有効になります。

【注意】
Astro 2.0~2.5の場合は、output: 'hybrid'がありませんので、代わりにoutput: 'server'を追加してください。この場合は、SSRをデフォルトとしたハイブリッドレンダリングが有効になります。

astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  output: 'hybrid'  // 追加
});

アダプターのインストール

コマンドを実行し、デプロイ先のホスティングサービスに対応したアダプターをインストールします。下のコマンドは参考としてNetlifyのアダプターのものです。アダプター自体のインストールとastro.config.mjsファイルへの適切な変更が一度に行われます。

npx astro add netlify

その他のホスティングサービスに対応したアダプターのインストールについては、こちらのAstro公式ドキュメントをご確認ください。

静的レンダリング設定(Astro 2.0~2.5の場合のみ実施)

Astro 2.0~2.5の場合、pagesディレクトリ配下がすべてSSRになります。プレビューページ以外はビルド時に静的レンダリングをするようにしたいので、pagesディレクトリ配下の全てのページファイルにexport const prerender = true;を追加してください。Astro 2.6以降の場合、pagesディレクトリ配下はすべて静的レンダリングとしたため、この設定は不要です。

追加するイメージはこのような形です。

src/pages/sample-page.astro
---
// 静的レンダリングを有効にする
export const prerender = true;  // 追加

// ...スクリプト
---
<html>
  <!-- ...テンプレート -->
</html>

プレビューページの実装

下のmicroCMS公式ブログの通りにAstroブログが作成されているとして、修正するポイントの説明を行います。

まずはブログ記事詳細ページのsrc/pages/[blogId].astroファイルをコピーして、src/pages/preview.astroファイルを作成してください。

次にsrc/pages/preview.astroに対して、下の修正を行ってください。

  • プレビューページをサーバサイドレンダリングとするため、export const prerender = falseを追加
  • src/pages/preview.astroファイルではパス取得は不要となるため、getStaticPaths関数を削除
  • URLパラメータから取得したblogIddraftKeyをもとに、記事の詳細情報を取得するように修正
src/pages/preview.astro
---
import Layout from "../layouts/Layout.astro";
import { getBlogs, getBlogDetail } from "../library/microcms";

// ==================== 修正箇所 ここから ====================

// サーバーサイドレンダリングを有効にする
export const prerender = false;

let blogId;
let draftKey;
let blog;

// URLパラメータを取得
try {
  if (Astro.request.method === "GET") {
    const url = new URL(Astro.request.url);
    const params = new URLSearchParams(url.search);
    blogId = params.get("blogId");
    draftKey = params.get("draftKey") || undefined;
  }
} catch (error) {
  console.error(error);
}

// ブログIDがない場合は404
if (!blogId) {
  return new Response(null, {
    status: 404,
    statusText: "Not found",
  });
}

// 記事の詳細情報を取得。取得できない場合は401を返す。
try {
  blog = await getBlogDetail(blogId as string, { draftKey: draftKey });
} catch {
  return new Response(null, {
    status: 401,
    statusText: "Invalid Blog ID or Draft Key",
  });
}

// ==================== 修正箇所 ここまで ====================

---

<Layout title="My first blog with Astro">
  <main>
    <h1 class="title">{blog.title}</h1>
    <p class="publishedAt">公開日時:{blog.publishedAt}</p>
    <div class="post" set:html={blog.content}></div>
  </main>
</Layout>

<style>
  main {
    margin: auto;
    padding: 1em;
    max-width: 60ch;
  }
</style>

以上で実装は完了です。

microCMSの設定

API設定>画面プレビューから、画面プレビューボタン押下時の遷移先URLの設定を行ってください。

遷移先URL

設定値は下の通りです。https://yourdomain.comの部分は自身のドメインに置き換えるようにしてください。

https://yourdomain.com/preview/?blogId={CONTENT_ID}&draftKey={DRAFT_KEY}

以上でmicroCMSの設定は完了です。

実装したソースコードをホスティングサービスにデプロイ後、microCMSの管理画面から画面プレビューが行えることを確認してください。

終わりに

Next.jsで出来ていたプレビューページのみのSSRを、Astroでも実現できないものか?と思ったことがきっかけで当記事を作成しました。当初は実現できないと思っていましたが、たまたま英語版の公式ドキュメントにハイブリッドレンダリングの記載がある(日本語版にはなかった...!)ことを知り、ここまでこぎつけることができました。

当記事の方法だと、ほぼ同じ処理のsrc/pages/[blogId].astroファイルとsrc/pages/preview.astroファイルが出来上がる形となります。このままでも動作しますが、共通処理をコンポーネント化することも検討されるとよいかもしれません。

Astroを使ってサイトを作成されている方の参考となれば幸いです。

参考

この記事は以下の情報を参考にしました。

更新履歴

  • 2023/04/24 初版
  • 2023/06/08 Astro 2.6にてハイブリッドレンダリングのデフォルトを静的レンダリングとする機能が正式にリリースされたためリライト

関連タグの記事

Ryota Kondo
Ryota Kondo

システムエンジニア・プログラマー|このブログサイトの運営もしており、思いついたことをまとめて記事を書いています💡|Twitterのフォローはお気軽に