---
title: 'Astro + Cloudflare Pagesでブログを作ったら体験が良かった'
description: 'Astroで静的サイトジェネレーターを使ったブログ構築の手順と、Cloudflare Pagesへのデプロイまでを簡単に解説します。'
pubDate: '2026-01-29T00:00:00.000Z'
tags: ['Programming', 'TypeScript']
source: 'https://qwqb.net/blog/create-astro-blog/'
---

import OptimizedImage from '@/components/OptimizedImage.astro';
import workersDeploy from './workers-deploy.jpg';
import customDomain from './custom-domain.jpg';
import dnsRecords from './dns-records.jpg';
import webPerformance from './web-performance.jpg';

[Astro](https://astro.build/) の存在は元々知っていたものの、「アイランドアーキテクチャってやつね（分かってない）」という感じで割とスルー気味でした。実際のところ、静的サイトを構築するような案件を最近やっていないので触れる機会がなかったという面が強いです。そのような訳で、ブログを作る形でしっかりと触ってみることにしました。

## なぜ Astro なのか

そもそも Astro の[独自性](https://docs.astro.build/en/concepts/why-astro/#features)はいくつかあります。主だったものは以下です。

- 構築が楽（ホスティングに上げやすい）
- [Gatsby](https://www.gatsbyjs.com/docs/glossary/static-site-generator/) とか [Next.js](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) みたいな痛みがない（画像最適化・ビルド最適化のめんどくささ）
- React などの資産を再利用する選択肢が取れる
- Lighthouse などのスコアが上げやすい（SSG は必須）

この辺りで考えていると Astro 一択になると思います。むしろ、SSG が流行ってから多くの反省を改善したのが Astro とも言えるかもしれません。

## 環境情報

- nvm: 0.40.1 (WSL 環境で初めて開発しましたが nvm で管理するのが快適です)
- node.js: v24.13.0
- npm: 11.6.2
- astro: 5.16.15

## セットアップ

セットアップコマンドを実行し、ブログテンプレートを選択。一から CSS を書くのもしたくないので、とりあえず TailwindCSS も入れておきます。

```bash
npm create astro@latest
```

```bash
npx astro add tailwind --yes
```

Prettier も入れます。本当は Biome を入れたいですが、意外と面倒事が多いのでエコシステムに乗っかって楽したいときはやはり Prettier かなと最近は強く感じます。

```bash
npm install --save-dev prettier prettier-plugin-astro prettier-plugin-tailwindcss prettier-plugin-organize-imports
```

なお、インストールしただけでは各プラグインが息をしないので、リポジトリのルートに `.prettierrc` 等を置いて読み込ませておく必要があります。

記事ページ表示用に TailwindCSS の Typography も追加してから global.css を設定しておきます。その他、Web フォントとかも入れておきたいところですが、モバイルの評価がだいぶ下がるので導入はしません。

```bash
npm install @tailwindcss/typography
```

```css
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
```

codeblock などのセットアップも最初からされているようで、ここまで記述してきたコードも言語指定でシンタックスハイライトがされるようになっています。あとは不要なテンプレートファイルなどを削除すればこの時点でブログのように利用できます。

Astro ブログテンプレートの良いところは `content/` 配下でデータベースのように記事を管理できる点です。加えて `content.config.ts` で zod を使ったスキーマの定義ができます。

例えばブログを書く上で、タグの表記揺れみたいなのを抑えたいといったシーンで zod に検知させて型エラーにすることができます。もちろん他にも色々なことができるはずです。

<details>
<summary>content.config.ts のサンプル</summary>

```ts
import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';

// 使いそうなタグを定義しておく
const MAIN_GENRES = ['Blog', 'Review', 'Programming', 'Study'] as const;
const LANGUAGES = ['TypeScript', 'Golang', 'Rust', 'Kotlin'] as const;
const TOOLS = ['Blender', 'Unity'] as const;
export const ALLOWED_TAGS = [...MAIN_GENRES, ...LANGUAGES, ...TOOLS] as const;

const blog = defineCollection({
  loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      pubDate: z.coerce.date(),
      updatedDate: z.coerce.date().optional(),
      heroImage: image().optional(),
      tags: z.array(z.enum(ALLOWED_TAGS)).optional(), // 追加
    }),
});

export const collections = { blog };
```

</details>

例えば frontmatter に以下のようなタグを追記してみます。

```markdown
---
title: 'hoge'
tags: ['Programming', 'TypeScript', 'fuga']
---
```

このようなときは、以下のようにエラーを出してくれます。

```plaintext
[ERROR] [InvalidContentEntryDataError] blog → create-astro-blog data does not match collection schema.
  tags.2**: **tags.2: Invalid enum value. Expected 'Programming' | 'TypeScript' ...中略... , received 'fuga'
```

画像に関しても自動的に最適化してくれるので、もはや静的サイトを作るうえですでにやることがありません。本当にいい時代になったと思います。

ただし、デフォルトの画像最適化パッケージ（Sharp）は Cloudflare Pages (Workers) 上では動きません。そのため、本番ビルドの段階で最適化を済ませてしまうよう `astro.config.mjs` 側にアダプターの設定を入れておく必要があります。

```js
// astro.config.mjs
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  // ...
  adapter: cloudflare({
    imageService: 'compile',
  }),
});
```

これを書いておかないと Cloudflare デプロイ時にビルドエラーでコケてしまうので要注意です。これさえ設定しておけば、ビルド時にいい感じに画像を最適化してくれます。

### Cloudflare 関連とデプロイ

Astro のプロジェクト内で以下のコマンドを実施し、Cloudflare Adapter を追加します。特に手動で設定することはありません。

```bash
npx astro add cloudflare
```

続いて Cloudflare Pages のセットアップをすればデプロイ完了です。

1. Github 上にリポジトリを作成しておく（ここまでの作業内容は push しておく）
2. Cloudflare の[ダッシュボード](https://dash.cloudflare.com/)に移動
3. ビルド > コンピューティングと AI > Workers & Pages に移動
4. 右上のアプリケーションを作成するボタンを押下
5. Github を選択し、リポジトリを選択
6. あとは画面に従って進める

Workers & Pages の自身のプロジェクトを開くと、以下のようにデプロイ状況が確認できます。デプロイが完了すると pages 用のドメインが発行されて、そこからアクセスが可能になります。

<OptimizedImage src={workersDeploy} alt="デプロイ状況の確認" />

カスタムドメインに関しても、自身のプロジェクトから設定を開き、カスタムドメインを選択した後に Cloudflare 上で所持しているドメインを入力するだけです。

<OptimizedImage src={customDomain} alt="カスタムドメイン設定" />

DNS レコードへ自動的に設定され、本当に何もやることがありません。すばらしいです。

<OptimizedImage src={dnsRecords} alt="DNSレコード設定" />

### さいごに

実際に触ってみると、Astro はセットアップからデプロイまでの体験がとても良かったです。デザイン調整などを除けばほとんど作業することはありませんでした。万が一つまずいても、今の時代は GitHub Copilot などにいくらでもサポートしてもらえる環境なので安心ですね。

PageSpeed Insights も問題なく 100 点でした。

<OptimizedImage src={webPerformance} alt="PageSpeed評価" />

今回作成したサイトのソースは非公開にしていますが、特別なことはほとんどしていないので、Astro を触ってみれば似たような構成はすぐに作れると思います。
