【実録】Astro × microCMS × Cloudflare Pagesで爆速メディアを立ち上げる!初期構築からトラブルシューティング、自動化まで完全解説

Webメディアの運営において、サイトの表示速度やサーバー運用のコスト・手間は常に大きな課題です。WordPressなどの従来型CMSでは、データベースの管理やキャッシュ設定、セキュリティ対策に追われることも少なくありません。
そこで今回、表示速度が極めて速く、保守管理が実質不要な構成として注目される「Astro + microCMS + Cloudflare Pages」を採用し、自社メディア基盤の初期構築を行いました。
本記事では、このスタックを選定した理由から、初期構築の手順、実際にデプロイ時に直面した「3つのエラー」とその解決策、そして記事入稿を完全自動化するWebhookの設定まで、包み隠さず記録として共有します。
1. 今回採用した技術スタック
運用の手離れの良さと、将来的なアクセス増に耐えうるインフラを目指し、以下の技術を選定しました。
- 静的サイトジェネレーター(SSG):Astro
必要なHTMLをビルド時に事前生成し、クライアント側への不要なJavaScript配信を極限まで削ることで、トップクラスの初期表示速度を実現します。
- ヘッドレスCMS:microCMS
日本発の使いやすい管理画面を持つクラウド型CMS。API経由で記事データをJSON形式で取得します。
- ホスティング & CI/CD:Cloudflare Pages
世界中に張り巡らされたエッジネットワーク上で高速配信。GitHubと連携した自動ビルドに加え、無料枠の制限も緩やかで個人〜中小メディアに最適です。
2. 実装のステップ:一覧表示から個別記事ページの生成まで
(1) microCMS クライアントの初期化
まずは公式SDK(microcms-js-sdk)を導入し、Cloudflareおよびローカル環境の環境変数からAPIキー等を読み込むクライアントを設定しました。
TypeScript
import { createClient } from "microcms-js-sdk";
export const client = createClient({
serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
apiKey: import.meta.env.MICROCMS_API_KEY,
});
(2) 動的ルーティング([id].astro)による個別記事の生成
Astroでブログ詳細ページを作る場合、src/pages/blog/[id].astro というファイルを作成し、getStaticPaths() 関数を使って全記事のURL(ID)をビルド時に解決させます。
コード スニペット
---
import { createClient } from "microcms-js-sdk";
const client = createClient({
serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
apiKey: import.meta.env.MICROCMS_API_KEY,
});
// ビルド時に生成すべき全記事のパス(ID)をmicroCMSから取得
export async function getStaticPaths() {
const client = createClient({
serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
apiKey: import.meta.env.MICROCMS_API_KEY,
});
const data = await client.getList({
endpoint: "blogs",
});
return data.contents.map((content) => ({
params: { id: content.id },
}));
}
const { id } = Astro.params;
// 対象記事の詳細データを取得
const blog = await client.getListDetail({
endpoint: "blogs",
contentId: id,
});
---
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>{blog.title} | マイ・テックメディア</title>
</head>
<body>
<a href="/">← 記事一覧に戻る</a>
<article>
<h1>{blog.title}</h1>
<p>公開日: {new Date(blog.publishedAt).toLocaleDateString("ja-JP")}</p>
<div set:html={blog.content} />
</article>
</body>
</html>
3. 【実録トラブルシューティング】デプロイ時に発生した3つの落とし穴
開発中、トップページの記事一覧からはリンク(例:/blog/t46acl_uw)が正しく出力されているのに、「クリックしても画面が変わらない」「404 Not Found になる」というトラブルに遭遇しました。
調査の過程で判明した原因と対処法は以下の通りです。
トラブル①:ファイルの配置ディレクトリミス
- 症状: 詳細ページのファイルを作成してプッシュしたはずなのに、URLにアクセスしてもページが存在しない。
- 原因: Astroでは
src/pages/配下のファイルのみがWebページとしてルーティングされますが、誤ってsrc/blog/[id].astroに配置してしまっていました。 - 解決策: Gitの移動コマンドで正しいディレクトリ(
src/pages/blog/[id].astro)へ移動させてコミットしました。Bash
git mv src/blog/[id].astro src/pages/blog/[id].astro git commit -m "fix: move blog detail template to src/pages/blog/[id].astro" git push origin main
トラブル②:フロントマター内の構文エラー(CompilerError)
- 症状: Cloudflare Pagesのビルドログで
[CompilerError] Expected a semicolon or an implicit semicolon after a statement, but found noneが発生し、ビルドが失敗する。 - 原因:
src/pages/index.astroの先頭ブロック(---に挟まれたコード)の書き換え時に構文の不整合が発生し、Vite/Rolldownのコンパイルが停止していました。 - 解決策: ファイル全体のコードを正規の構文で完全に上書き保存し、ローカル環境で事前に
npm run buildを実行してエラーが解消されたことを確認してからプッシュしました。
トラブル③:ビルド失敗による古いバージョンの配信
- 症状: Gitプッシュを行っても、本番サイトに最新の変更が反映されない。
- 原因: Cloudflare Pagesはビルドに失敗すると、サイトが落ちるのを防ぐために直前の正常にビルドされたバージョン(Active状態)を配信し続けます。管理画面上のステータスが
No deployment availableになっていることに気付くのが遅れました。 - 解決策: Cloudflare Pagesの「Deployments」ログを確認し、最新コミットが緑のチェック(
Deploy successful!)になるまで原因を潰すことで、正常に個別記事ページが表示されるようになりました。
4. 自動化の要:microCMS Webhook連携による「Git操作不要」の運用フロー
静的サイト(SSG)の弱点は、「記事を更新・公開するたびに再ビルドが必要な点」です。
非エンジニアでも直感的に運用できるように、microCMSで記事を公開した瞬間にCloudflare Pagesへ自動通知して再デプロイを走らせる仕組みを構築しました。
- Cloudflare Pages側でDeploy hookを発行
- プロジェクト設定(Settings > Builds & deployments > Deploy hooks)から、
mainブランチを対象としたフックURLを生成。
- プロジェクト設定(Settings > Builds & deployments > Deploy hooks)から、
- microCMS側でWebhookを登録
- API設定(API設定 > Webhook)を開き、生成されたURLを登録。
- トリガーに「コンテンツの公開」「コンテンツの更新」「コンテンツの削除」を指定。
これにより、執筆者は管理画面で「公開」ボタンを押すだけで、数十秒後には世界中に最新記事が反映される完全自動化の更新フローが完成しました。
5. まとめと今後のロードマップ
Astro + microCMS + Cloudflare Pages の組み合わせにより、以下のメリットを享受できる強固なメディア基盤が立ち上がりました。
- 超高速な表示速度(Core Web Vitals に極めて有利)
- サーバー管理・WordPress保守の手間とコストがゼロ
- Webhook連携による直感的な入稿・自動反映
今後は、さらにメディアとしての完成度を高めるため、以下のステップを進めていく予定です:
- Tailwind CSS / Typographyプラグインによる記事本文のスタイリング
- SNSシェア用のOGP画像やSEOメタタグの動的埋め込み
- アクセス解析(GA4・BigQuery連携)によるデータ収集体制の整備
個人メディアやオウンドメディアを軽量かつモダンに構築したい方は、ぜひ参考にしてみてください。