Cloudflare Pages + Astro + React

Page content

React とは

Meta(旧Facebook)が開発したJavaScriptライブラリで、UIを構築するために使われます。


核心的な考え方

コンポーネントベース

UIを小さな部品(コンポーネント)に分割して組み合わせます。

// ボタンコンポーネント
function Button({ label, onClick }) {
  return <button onClick={onClick}>{label}</button>;
}

// 上のコンポーネントを使う
function App() {
  return <Button label="クリック" onClick={() => alert('押した!')} />;
}

宣言的UI

「どう変えるか」ではなく「どう見えるべきか」を書くだけでOKです。

// stateが変わると自動的に画面が更新される
function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

主な特徴

JSX — JavaScriptの中にHTMLのような構文が書ける

State(状態管理) — データが変わると画面が自動更新される

Virtual DOM — 差分だけを効率よく更新するので高速

豊富なエコシステム — ライブラリや情報が非常に多い


Astroの文脈でのReact

Astroは基本的にサーバーでHTMLを生成します。Reactはインタラクティブな部分だけに使うイメージです。

Astroページ(静的)
  └── Reactコンポーネント(ボタン、フォーム、アニメーションなど動く部分)

静的な部分はReact不要、動きが必要な部分だけReactを使えるので、軽くて速いサイトが作れます。


Cloudflare Pages + Astro + React のセットアップ方法をご説明します。

1. プロジェクト作成

npm create astro@latest my-app
cd my-app

2. Reactインテグレーション追加

npx astro add react

これで astro.config.mjs に自動で設定が追加されます。

3. Cloudflare アダプター追加

npx astro add cloudflare

astro.config.mjs がこのようになります:

import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server', // または 'hybrid'
  adapter: cloudflare(),
  integrations: [react()],
});

4. Reactコンポーネントを作成

src/components/Counter.tsx

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

5. Astroページで使う

src/pages/index.astro

---
import Counter from '../components/Counter';
---

<html>
  <body>
    <!-- client:load でインタラクティブにする -->
    <Counter client:load />
  </body>
</html>

6. Cloudflare Pages にデプロイ

npm run build

Cloudflare Dashboard で:

  • フレームワーク: Astro
  • ビルドコマンド: npm run build
  • 出力ディレクトリ: dist

クライアントディレクティブについて

Astroでは client:* ディレクティブでいつReactをハイドレートするか制御できます:

ディレクティブ タイミング
client:load ページ読み込み時すぐ
client:idle ブラウザがアイドル状態のとき
client:visible 要素が画面に見えたとき
client:only="react" サーバーレンダリングなし(クライアントのみ)

「React単体」とは、AstroやNext.jsなどのフレームワークを使わず、Reactだけでアプリを作る構成です。


仕組み

ブラウザがアクセス
    ↓
空っぽに近いHTMLが返ってくる
    ↓
JavaScriptが読み込まれる
    ↓
ReactがブラウザでUIを生成(CSR)

すべてクライアント(ブラウザ)で動くので、CSR(Client Side Rendering) とも呼ばれます。


Astro + SSRとの比較

React単体(CSR) Astro + SSR
HTMLの生成 ブラウザ サーバー
初期表示速度 遅め 速い
SEO 弱い 強い
サーバー不要
インタラクション 全部React 必要な部分だけReact
構成のシンプルさ シンプル やや複雑

コード例

Astro版(SSR)

---
// サーバーでデータ取得
const posts = await fetch('/api/posts').then(r => r.json());
---
<!-- サーバーでHTMLが生成される -->
<ul>
  {posts.map(p => <li>{p.title}</li>)}
</ul>

React単体版(CSR)

function Posts() {
  const [posts, setPosts] = useState([]);

  // ブラウザで読み込み後にデータ取得
  useEffect(() => {
    fetch('/api/posts')
      .then(r => r.json())
      .then(setPosts);
  }, []);

  return (
    <ul>
      {posts.map(p => <li key={p.id}>{p.title}</li>)}
    </ul>
  );
}

React単体が向いているケース

  • 管理画面・ダッシュボード — SEO不要、インタラクションが多い
  • 社内ツール — 認証後にしか見えないページ
  • SPAアプリ — Twitterのようなページ遷移なしのアプリ

Astro + SSRが向いているケース

  • ブログ・ECサイト — SEOが重要
  • ランディングページ — 初期表示速度が重要
  • 静的コンテンツが多いサイト — 動きが少ない

Cloudflare Pagesにデプロイする場合

React単体(Vite使用)なら非常にシンプルです。

npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run build

Cloudflare Dashboardの設定:

  • ビルドコマンド: npm run build
  • 出力ディレクトリ: dist

Cloudflareアダプターも不要で、ただの静的ファイルとしてデプロイできます。