microCMS

AstroとmicroCMSでつくるブログサイト

松田 承一

=== 更新履歴
2024/1/10: MicroCMSQueriesのインポートに関して、Type-Only Imports and Exportを使用するように変更しました。
===

こんにちは、microCMSの松田です。
今回は2022年8月に1.0バージョンを公開したAstroを使ったチュートリアルをお届けいたします。

Astroとは?

Astroは多機能で効率的な静的サイトジェネレーターの一つです。
そのGitHubリポジトリには2022年9月時点で2万弱のスターが付けられており、開発者コミュニティから高い評価を受けています。

https://astro.build/

数ある静的サイトジェネレーターの中でなぜAstroを選ぶのか公式のドキュメントで解説されています。
https://docs.astro.build/en/concepts/why-astro/

ここで書かれていることを簡潔にまとめると以下のような内容です。

  • Astroはウェブアプリではなくウェブサイトを作るために用意されたWebフレームワークです。
  • Astroはクライアントサイドレンダリングよりもサーバサイドレンダリングを可能な限り使用します。ただし、HTML、CSS、JavaScriptのみで開発は可能です。
  • デフォルト設定で、パフォーマンスが最適化された高速なサイトを構築できます。
  • React、Preact、Svelte、Vue、Solid、Litなど様々なUIフレームワークをサポートしています。徐々に利用技術を差し替えていくことも可能です。
  • 100以上の統合機能が用意されており、CMSやホスティングサービスとの接続も自由です。


そしてAstroを語る上でもう一つ欠かせないのがAstro Islandsです。
これも公式のドキュメントで説明されています。
https://docs.astro.build/en/concepts/islands/

簡単に解説すると、ページの各UIコンポーネントを別モノとして扱うことができます。
これによりコンポーネント間の優先度設定によるパフォーマンス調整やコンポーネント毎にUIフレームワークを変えられることがメリットとなっています。
React 18でも導入されたSelective Hydrationにも近い考え方となっていますね。

https://jasonformat.com/islands-architecture/

プロジェクトのセットアップ

それではAstroの大枠を知れたところでブログサイトの開発に取り掛かっていきましょう。
まずはプロジェクトを作成します。

デフォルトもしくはrecommendedな設定を選んでいけば問題はありませんが、はじめての場合はWhich template sould you like to use?の質問で表示されるテンプレートでBlogなどを選べばAstroで作るサイトの雰囲気をつかみやすいでしょう。

$ npm create astro@latest  
Welcome to Astro! (create-astro v1.0.1)
Lets walk through setting up your new Astro project.
✔ Where would you like to create your new project? … my-fisrt-astro-blog
✔ Which template would you like to use? › Just the basics (recommended)
✔ Template copied!
✔ Would you like to install npm dependencies? (recommended) … yes
✔ Packages installed!
✔ Would you like to initialize a new git repository? (optional) … yes
✔ Git repository created!
✔ How would you like to setup TypeScript? › Strict (recommended)
✔ TypeScript settings applied!
✔ Setup complete.
✔ Ready for liftoff!

 Next steps 

You can now cd into the my-fisrt-astro-blog project directory.
Run npm run dev to start the Astro dev server. CTRL-C to close.
Add frameworks like react and tailwind to your project using astro add

Stuck? Come join us at https://astro.build/chat
Good luck out there, astronaut.

ローカル環境でサイトを確認してみる

次に手元のマシン内で開発サーバを立ち上げてサイトを確認してみます。

$ cd my-fisrt-astro-blog
$ npm run dev

> @example/basics@0.0.1 dev
> astro dev

  🚀  astro  v1.2.2 started in 35ms
  ┃ Local    http://localhost:3000/
  ┃ Network  use --host to expose


この状態でhttp://localhost:3000/にアクセスしましょう。以下のような画面を確認できればOKです。

microCMSアクセスへの準備をする

今回、ブログの情報はmicroCMSより取得します。
そのため環境変数にてmicroCMSへのアクセスに必要な情報を定義しておく必要があります。

環境変数の設定

Astroでは環境変数はプロジェクトルート( package.json が存在する階層)に .env ファイルを用意することで定義可能です。
microCMSの登録情報やAPIキー情報を確認し、以下のように記述しておきましょう。

MICROCMS_SERVICE_DOMAIN=<YOUR_SERVICE> # .microcms.io は含まない値
MICROCMS_API_KEY=<YOUR_KEY_VALUE>


参考:環境変数 🚀 Astroドキュメント

microCMS JavaScript SDKのインストール

microCMSをAstroから呼び出すためにmicrocms-js-sdkを導入しておきましょう。
導入は1コマンドで完了します。こちらもプロジェクトルートで実行しましょう。

$ npm install microcms-js-sdk


ブログ記事一覧を作成する

それではいよいよブログ記事を作成していきます。

まずはmicroCMSにブログ(blogs)というAPIを用意します。


APIの型の選択ではリスト形式を選択してください。


フィールドは以下のように指定します。
この部分は画面上部のファイルインポート機能を使って簡単に設定を行うことも可能です。本記事の上部でも示したastro-blog-schema.jsonをダウンロードし指定を行ってください。

APIが作成できたら記事も2つほど作成しておきます。

ここまで準備ができたらAstroのソースコード記載を進めていきましょう。今回はトップページにブログ一覧が並んでいるサイトを想定します。
microCMSへの呼び出しは一覧画面と詳細画面のそれぞれで行われるため、まずはsrc/library/microcms.tsにAPI呼び出しのための実装を用意します。

//SDK利用準備
import type { MicroCMSQueries } from "microcms-js-sdk";
import { createClient } 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,
  });
};


次にsrc/pages/index.astro の内容を以下のように書き換えます。このファイルがルートパス(http://localhost:3000/)にアクセスした際に呼び出されます。

---
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>

先頭の--- はマークダウンのFront-matterと同じような考え方であり、Astroの場合はファイル先頭でJavaScript処理を記述できます。(デフォルトではビルド時にサーバサイドで呼び出され、ビルド後のサイトにはJavaScriptコードは残りません。scriptタグやSelective Hydrationなどを利用する場合にビルド後もJavaScriptコードが残ります。)
この部分でmicroCMSの記事一覧を呼び出し、リスト要素として画面表示しています。

この状態でブラウザでの表示は以下のようになります。microCMSから取得した記事の一覧を表示できました!

ブログ記事詳細を作成する

ここまでの作業では詳細ページを作成していないので、リンクを押下して遷移すると以下のようなNot Found画面が表示されているはずです。
Not Foundとならないように詳細画面を作成していきましょう。

ルーティング設定をする

Astroでは基本的に src/pages 以下のファイル名がウェブサイトのパスと対応しますが、今回のようにパスの値が動的に変わる場合には動的ルーティングを設定する必要があります。
参考:ルーティング 🚀 Astroドキュメント

今回はhttp://localhost:3000/記事idといったパスでアクセスできるように src/pages/[blogId].astroファイルを作成し、以下のように記述します。

---
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}></div>
  </main>
</Layout>

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

getStaticPathsはこの動的なパスがどういった値を取り得るかを指定するために用意します。
またmicroCMSのリッチエディタではHTML文字列がそのまま返却されるため、set:htmlを使ってHTMLを画面にそのまま表示しています。
<div class="post">{blog.content}</div>ではHTML部分がエスケープされてしまい画面上にそのまま表示されてしまうためご注意ください。

上記の説明に関連したドキュメントは以下の通りです。


ここまでの記述が完了すると以下のように詳細画面も表示されます。
microCMSの入稿内容を変更すると記事表示も変わることをご確認ください。

ホスティングしてサイト公開する

ブログサイトの一覧と詳細を表示できるようになったため、サイト公開に進みます。
まずはAstroで作ったサイトのビルドとプレビューについて理解しましょう。

ウェブサイトのビルドは1コマンドを実行するのみと非常に簡単です。

$ npm run build

ビルドが成功した場合は./distにサイトが出力されます。
出力されたサイトの確認は以下のコマンドです。

$ npm run preview


概要を理解できたためホスティングサービスを利用して作成したサイトを公開します。
ビルド後のファイルは単純なHTML/CSS等ですのであらゆる箇所にホスティングができますが、いくつかのサービスは公式ドキュメントでその手順が詳しく説明されています。
デプロイ 🚀 Astroドキュメント

その中でも特にNetlifyを使う方法は特に簡単です。
プロジェクトルートに netlify.tomlファイルを作成し、以下のように記述します。

[build]
  command = "npm run build"
  publish = "dist"


作成できたらここまでで作成したプロジェクトをGitHubリポジトリとして登録しNetlifyと連携させましょう。
この部分の詳しい手順はNuxt.jsのチュートリアル記事内にも記載があるのでご参照ください。

サイト公開できたら本記事の内容は完了です!おめでとうございます🎉

今後の予定

AstroとmicroCMSを組み合わせてつくるブログサイトについて解説してきました。
今回は簡単なところまでの着手となりましたが、今後は以下についても記事化する予定です。
ご希望の内容などがございましたら画面右下のチャットからフィードバックをお送りいただけますと幸いです。

  • ヘッダとフッタを追加しSelective Hydrationも行う
  • Astro標準のページ分割機能を利用してページング実装をする
  • コンポーネント構造を整理する
  • 静的サイトではなくSSRでウェブサイトを配信する


本記事は以上です。ここまでお読みいただき誠にありがとうございました。

まずは、無料で試してみましょう。

APIベースの日本製ヘッドレスCMS「microCMS」を使えば、 ものの数分でAPIの作成ができます。

microCMSを無料で始める

microCMSについてお問い合わせ

初期費用無料・14日間の無料トライアル付き。ご不明な点はお気軽にお問い合わせください。

お問い合わせ

microCMS公式アカウント

microCMSは各公式アカウントで最新情報をお届けしています。
フォローよろしくお願いします。

  • X
  • Discord
  • github

ABOUT ME

松田 承一
株式会社microCMSの代表 / 家族=👨‍👩‍👧 / ヤフー→大学教員など→現職 / 管理画面付きAPIがすぐに作れるmicroCMSというサービス作ってます。