AstroとmicroCMSを利用したブログの構築方法を紹介!

カテゴリー
公開日 最終更新日
AstroとmicroCMSを利用したブログの構築方法を紹介!

はじめに

このページではAstroとmicroCMSを組み合わせてSSR(Server Side Rendering)のブログを作成する方法を紹介します。今回目指す挙動としては、microCMSでブログを更新すると自動でビルド処理を走らせてページを追加・更新させます。

この記事を作成するに至った経緯として、このブログはAstro × microCMS × netlifyの構成で運用をしているのですが、microCMS公式ドキュメントの構築方法ではページを追加するたびに手動でビルドをさせる必要があり手間に感じていました。色々方法がないか模索をしていたところ、microCMSにデフォルトで備わっているWebhookを利用してビルドさせられそうだったので記事にしようと思いました。
同じような方法でブログを作成しようと考えている方の一助となれば幸いです。

SSG(Static Site Generation)とは?

構築方法についてまとめる前にSSGについてまとめます。SSG(Static Site Generation)は予め静的なHTMLファイルをレンダリングしておき、それを配信する方法です。この方式のメリットとしては、JSなどを取り除いた形でHTMLファイルを配信するため表示までが非常に高速です。

そのため、閲覧者によらず内容が異ならず更新頻度が低いページに関してはSSGで作成すると良いユーザーエクスペリエンスが得られます。

SSR(Server Side Rendering)との違いは?

SSGと似た言葉にSSRがあります。SSR(Server Side Rendering)とは、その名の通り、ページ遷移のたびにHTTPリクエストが走るアーキテクチャのことです。レンダリングをサーバー側で行えるため、ブラウザ側の負担が減り初回読み込み時に時間がかかることがありません。ReactやVue.jsなどのフレームワークは基本的に、クライアント側でレンダリングを行う為、クライアントで処理するJavaScriptの量が膨大でしたがそれを解決するアーキテクチャとなります。

AstroとmicroCMSでSSRのブログを作成する

このセクションでは実際にAstroとmicroCMSを利用してSSRを実現する方法を紹介していきます。大まかな流れとしては以下のとおりです。

  1. Astroプロジェクトの作成
  2. microCMSの設定
  3. netlifyの設定

今回は、netlifyを使用していますが、Vercelなどでもおおよそ同じ方法で実装できると思います。

Astroプロジェクトの作成

公開したいサイトを構築していきます。今回実装するサイトの構成は以下の通りです。

project/
┗public/
┗src/
|   └pages
|       ┗index.astro
|       ┗[blogId].astro
|   ┗components/
|       ┗...componentsが入る
|   ┗library
|       ┗microcms.ts
└.env
└astro.config.mjs

その他にも諸々の設定ファイル等はありますがおおよそ上のような構成です。

それでは、Astro公式ドキュメントにならって構築を進めます。

  1. ターミナルを開き、Astroプロジェクトを配置したいディレクトリで以下のコマンドを実行します。
npm create astro@latest
  1. 色々聞かれるので適当に答えていきます
     astro   Launch sequence initiated.
    
    ╭─────╮  Houston:
    
       dir   Where should we create your new project?
             ./molecular-magnitude
    
      tmpl   How would you like to start your new project?
             Include sample files
     ██████  Template copying...
    
      deps   Install dependencies?
             Yes
     ██████  Installing dependencies with npm...
    
        ts   Do you plan to write TypeScript?
             Yes
    
       use   How strict should TypeScript be?
             Strict
     ██████  TypeScript customizing...
    
       git   Initialize a new git repository?
             Yes
          ◼  Sounds good! You can always run git init manually.
    
      next   Liftoff confirmed. Explore your project!
    
             Enter your project directory using cd ./molecular-magnitude 
             Run npm run dev to start the dev server. CTRL+C to stop.
             Add frameworks like react or tailwind using astro add.
    
             Stuck? Join us at https://astro.build/chat
    
    ╭─────╮  Houston:
    │ ◠ ◡ ◠  Good luck out there, astronaut! 🚀
    ╰─────╯
    
  2. ターミナル上で作成したプロジェクトへ移動し、 npm run devコマンドを実行してlocalhostを立ち上げます
  3. 画像のように立ち上げることができました

これでAstroプロジェクトの立ち上げが完了しました

microCMSを接続する

次にmicroCMSの設定を行っていきます。ここはmicroCMS公式ドキュメントを参考に設定をしていきます。詳細ついては以下のサイトを参考にしてください。

  1. microCMSに会員登録が完了したら、サービス情報を入力し新規サービスを作成します。今回は「blog」という名前にします
  1. サービスの作成が完了したら、APIを作成します。今回は「ブログ」テンプレートを利用します
  2. APIの作成が完了したら適当に記事を何個か追加していきます。今回はデフォルトの記事を含めて3記事用意しました

  3. 記事の用意が完了したらAstroで必要なファイルを用意します。 ターミナル上で npm install microcms-js-sdkを実行した後 src/library/microcms.ts を用意して以下のように入力します
    //SDK利用準備
    import { createClient, MicroCMSQueries } from "microcms-js-sdk";
    const client = createClient({
      serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
      apiKey: import.meta.env.MICROCMS_API_KEY,
    });
    
    //型定義
    export type Blog = {
      id: string;
      createdAt: string;
      updatedAt: string;
      publishedAt: string;
      revisedAt: string;
      title: string;
      content: string;
    };
    export type BlogResponse = {
      totalCount: number;
      offset: number;
      limit: number;
      contents: Blog[];
    };
    
    //APIの呼び出し
    export const getBlogs = async (queries?: MicroCMSQueries) => {
      return await client.get<BlogResponse>({ endpoint: "blogs", queries });
    };
    export const getBlogDetail = async (
      contentId: string,
      queries?: MicroCMSQueries
    ) => {
      return await client.getListDetail<Blog>({
        endpoint: "blogs",
        contentId,
        queries,
      });
    };
    1. 完了したら src/pages/index.astroを開き、以下のページ上部に以下のように記載をします。これは、microCMS上の記事をすべて取得し出力します
      import Layout from "../layouts/Layout.astro";
      
      //microCMS呼び出し
      import { getBlogs } from "../library/microcms";
      const response = await getBlogs({ fields: ["id", "title"] });
      ---
      
      <Layout title="My first blog with Astro">
        <main>
          <ul>
            {
              response.contents.map((content: any) => (
                <li>
                  <a href={content.id}>{content.title}</a>
                </li>
              ))
            }
          </ul>
        </main>
      </Layout>
      
      <style>
        main {
          margin: auto;
          padding: 1em;
          max-width: 60ch;
        }
      </style>
                            
  1. 次に環境変数の設定を行います。プロジェクトルート( srcなどと同階層)に .envを作成して以下のように記述します
    MICROCMS_SERVICE_DOMAIN=<YOUR_SERVICE> # .microcms.io は含まない値
    MICROCMS_API_KEY=<YOUR_KEY_VALUE>
  2. 次に、管理画面の左上にある歯車マークから[APIキー]をクリックします
  3. 以下のように、APIキーが表示されるのでコピーをし .env内の <YOUR_KEY_VALUE>に入力します。同様にして画面左上のサービス名(今回であれば occ88rw82w<YOUR_SERVICE>に入力します

入力が完了したら以下のように記事一覧が取得できているかと思います。(見づらかったので背景色を白に変更しました)

microCMSから記事を取得して表示する

AstroとmicroCMSの連携が完了したのでここからは記事内容を取得する方法を紹介します。現段階ではトップページのリンクをクリックしても404 Not Foundが返ってくるかと思います。

今回は、 domainName.com/[記事ID]という風なURLにしたいので src/pages/[blogId}.astroというファイルを作成します。このブラケットで囲んだファイル名にすることで動的なルーティングを実現することができます。詳しくはこのブログの以下の記事で紹介していますので興味のある方は読んでみてください。

では、記事内容を表示していきます。

  1. src/pages/[blogId].astroを作成します
  2. 今回、レイアウトはトップページと同じものを使用するので src/layouts/Layout.astroを読み込みます
  3. ヘッド内に記事内容を読み込む処理を書きます。今回は以下のようにしました
    ---
    import Layout from "../layouts/Layout.astro";
    import { getBlogs, getBlogDetail } from "../library/microcms";
    
    // 詳細記事ページの全パスを取得
    export async function getStaticPaths() {
        const response = await getBlogs({ fields: ["id"] });
        return response.contents.map((content: any) => ({
            params: {
                blogId: content.id,
            },
        }));
    }
    
    //記事の詳細情報を取得
    const { blogId } = Astro.params;
    const blog = await getBlogDetail(blogId as string);
    ---
    
    <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} />
        </main>
    </Layout>
    
    <style>
        main {
            margin: auto;
            padding: 1em;
            max-width: 60ch;
        }
    </style>
    
  4. 記事を表示することができました!

記事の表示まで進める事ができました。スタイルなどは当てていないので全く見栄えは良くないです。

ここからは、netlifyと連携して実際にブログをデプロイするところまで進めます。

netlifyの設定

このセクションでは、microCMSとnetlifyを連携して記事を公開したら自動でビルドをさせる手順について紹介をします。サイトのデプロイ方法に関してはAstro公式ドキュメントを参考にしてください。

デプロイにあたり、環境変数の設定が必要となるので以下にその説明を記載します。

  1. 環境変数の設定を設定します。netlifyでデプロイするサイトの詳細を開き画面左のメニューから[Site Configuration]>[Environment variables]>[Add a variable]をクリックします
  2. [Import from a .env file]を選択することで .envファイルをコピペするだけで設定ができるのでこちらを選択します
  3. 入力が完了したら[Import variables]をクリックします

以上で環境変数の設定は完了です。うまくビルドできることを確認します。

デプロイが完了したら、次にWebhookの設定をしていきます。

  1. netlify上の[Site configuration]>[Build & deploy]内のBuild hooksから[Add build hook]をクリックします
  2. hook名とbranchを指定したらとして、[Save]をクリックします。ここで表示されるURLを後ほど使用するのでコピーしておいてください。
  3. コピーが完了したらmicroCMSで設定をします。管理画面の左から[コンテンツ(API)]>[ブログ]をクリックし画面右上の[API設定]>[Webhook]をクリックします
  4. 画面中央の[+追加]をクリックして表示される一覧からNetlifyを選択します
  5. Webhook名を適当につけて先程コピーしておいたURLを入力します
  6. 入力が済んだら画面を下までスクロールして[+追加]をクリックします

これでWebhookの連携が完了です。記事を公開すると自動でビルド→公開まで進めてくれます

終わりに

いかがでしたでしょうか。はじめにmicroCMSを採用してAstroサイトを構築しようとしたときにドキュメントにWebhook方式が載っていなかったのでSSRにするしかないかと思っていましたが色々調べたところSSGのまま気軽に公開できそうでしたので記事を作成しました。同じような構成を考えている方の一助となれば幸いです。