はじめに
今回、自分のテックブログを作成するにあたって、「軽量かつなるべく手軽に作成・デプロイしたい」と考え、以下の技術選定を行いました。
※cloudflare は事前にアカウントの作成が必要です。
自分向けの備忘録にはなりますが、同じ構成を使用したい方の参考の 1 つになれば幸いです。
プロジェクトの作成
今回、パッケージマネージャーは pnpm を採用しました。
お好きなパッケージマネージャーで問題ないかと思います。
主要パッケージのインストール
pnpm create astro@latestpnpm astro add tailwindpnpm astro add cloudflareディレクトリ構成は以下のようにしました。 基本的には astro をインストールした際のセットアップウィザードで選択する blog テンプレートをそのまま使用しています。
├── astro.config.mjs # Astroの設定ファイル├── public/ # 静的ファイル(robots.txtやfaviconなど)└── src/ ├── content.config.ts # コンテンツコレクションの型定義(スキーマ) ├── assets/ # 画像などのアセット ├── components/ # コンポーネント置き場 ├── layouts/ # ページ共通のレイアウト │ └── Layout.astro # <head>タグや共通ヘッダーなどを記述 ├── pages/ # ページルーティング │ ├── index.astro # トップページ │ ├── blog/ │ └── [...id].astro # 記事詳細ページ(動的ルート) │ └── styles/ └── global.css # グローバルスタイルページ部分の作成
まずはざっと共通レイアウトの作成を行なっていきます。(ヘッダーだったり、フッターだったり etc…)
src/layouts/に共通レイアウトを設置します。
背景色を設定したり、全ページで共通で設置するヘッダー、フッターを配置するのが個人的なオススメです。
<slot />部分はレンダリングされるコンテンツを渡す部分です。
これから作成していく記事部分は<slot />にレンダリングされていきます。
<!doctype html><html lang="ja"><head class="bg-slate-900 text-white py-4 "> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /></head> <body> <header class="bg-slate-900" py-4 border-b </header> <slot /> <Footer /> </body></html>コンテンツの定義(Schema)
src/content.config.ts に記事が持つべきデータおよび構成を定義していきます。
Astro の機能であるContent Collectionを使用する際に必須なファイルです。
これによって、記事にタイトルを書き忘れたり、日付のフォーマットを間違えたりした時にビルドエラーで気づけるようになったりと色々と便利です。
今回は以下のような構成にしました。
import { defineCollection, z } from "astro:content";import { glob } from "astro/loaders";
const blog = defineCollection({ // マークダウンファイルの読み込み設定 loader: glob({ pattern: "**/*.md", base: "./src/blog" }), schema: z.object({ title: z.string(), //タイトル description: z.string(), //概要・説明 pubDate: z.coerce.date(), //作成日 updatedDate: z.coerce.date().optional(), //更新日 tags: z.array(z.string()).default([]), //タグ }),});
export const collections = { blog };記事ページの生成と動的ルーティング
次にMarkdownファイルを元に記事を生成するページを作成していきます。 src/pages/blog/[…id].astro というファイル名にすることで、記事IDに応じたURL(例: /blog/first-post)が自動で割り当てられます。
import { getCollection, render } from "astro:content";import Layout from "../../layouts/Layout.astro";
// 存在する記事ID(ファイルパス)をすべて取得してページを生成するexport async function getStaticPaths() { const posts = await getCollection("blog"); return posts.map((post) => ({ params: { id: post.id }, props: { post }, }));}
const { post } = Astro.props;const { Content } = await render(post);
---
<Layout title={post.data.title}> <article class="prose prose-invert max-w-none"> <h1>{post.data.title}</h1> <div>{post.data.pubDate.toLocaleDateString()}</div>
<Content /> </article></Layout>getStaticPaths 関数で記事データを取得し、render 関数でMarkdownをHTMLに変換しています。 これで、Markdownファイルを追加するだけで、自動的にブログ記事ページが生成されるようになりました。
Markdownファイルを記述する
ここまでくると最後はMarkdownファイルを作成するのみです。 これまで作成してきたのはMarkdownファイルを表示するための骨格、箱と表現すべきでしょうか。
ここで1つ注意すべきなのはMarkdownファイル先頭でcontent.config.tsに記述したSchemaを定義してあげる必要があります。
後は通常通りのMarkdown記述で問題ありません。
---title: "AstroとCloudflare Pagesで技術記事を立ち上げてみた"description: "Astroで作成したテックブログをCloudflare Pagesにデプロイする"pubDate: "2025-12-31"tags: ["Astro", "Tech", "Cloudflare", Tailwind Css]---Cloudflare Pages へのデプロイ
最後の工程はデプロイです。 Cloudflare Pages を使えば、GitHub と連携するだけで自動的にデプロイされるのでかなりお手軽です。
※事前に Cloudflare へのサインインが必要です。
-
Workers & Pages ページの画面上部にある「アプリケーションを作成する」を押下します。

-
画面下部の「Pages で始める」を選択し、「Gitに接続」を選びます。
-
今回作成したリポジトリを選択します。
-
ビルド設定画面で、フレームワークプリセットとして 「Astro」 を選択します。
-
「保存してデプロイ」を押すと、ビルドが始まります。
ビルドが通るとデプロイ成功になります。 表示されているURLをクリックして画面が表示されれば完了です。
最後に
今回はなるべく簡単に立ち上げましたが、Astro にはまだまだ便利な機能がたくさんあります。 本ブログサイトにも実装されている目次機能や作成中の記事を本番環境に表示させない機能などの実装もしてみてもいいかもしれません。
最後まで読んでいただきありがとうございました。