本文へスキップ
Acecore

Astro + Cloudflareで公式サイトを機能拡張する全体設計

by Gui
目次
Astro + Cloudflareで公式サイトを機能拡張する全体設計

AstroとCloudflare Pagesで静的サイトを作ると、最初はページを速く安全に配信できれば十分です。

しかし運用を続けると、CMSで更新したい、多言語で出したい、AIチャットで訪問者を案内したい、フォームに文脈を渡したい、コメント欄も置きたい、という機能追加が出てきます。

この記事は、それらを どの順番で入れるか、どのレイヤーに置くか、どの記事を読めばよいか をまとめるインデックスです。Acecore公式サイトの実装を例にしながら、他のAstro + Cloudflare構成にも真似しやすい形で整理します。

結論

公式サイトを育てるときは、最初に「どこまでを静的HTMLにするか」「どこからをAPIにするか」「誰がコンテンツを更新するか」を分けるのが大事です。

Acecoreでは、次のように分担しました。

レイヤー担当するもの
Astroページ生成、ブログ、OGP、RSS、sitemap、UI
CloudflarePages配信、Pages Functions、D1、Turnstile
GitHubPRレビュー、CMS編集差分、翻訳差分、履歴
Sveltia CMS日本語source、著者、タグ、画像、ページ文言
OpenAI API問い合わせAIの回答生成
Pagefind静的HTMLに含める検索対象の索引

この分け方にすると、機能を増やしても「全部をCMSに入れる」「全部を外部SaaSに投げる」「全部をクライアント側で頑張る」状態になりません。

1. まず静的サイトとして強くする

土台はAstroです。

公式サイトの大半は、毎リクエストでサーバー処理をする必要がありません。

  • サービス紹介
  • 会社概要
  • 制作事例
  • ブログ記事
  • 著者ページ
  • タグページ
  • RSS
  • sitemap
  • OGP

これらはbuild時に静的HTMLとして生成できます。

静的HTMLで出せるものは、なるべく静的に出します。これにより、表示速度、キャッシュ、検索エンジンへの渡しやすさ、障害時の影響範囲が安定します。

一方で、問い合わせAIやコメント投稿のように、リクエストごとの処理が必要なものだけをCloudflare Pages Functionsへ出します。

ここを最初に分けておくと、機能追加のたびに「これはAstroのbuild時に解決するのか」「Cloudflare側のAPIにするのか」を判断しやすくなります。

2. 動的機能はCloudflare側の小さなAPIにする

静的サイトにも、どうしても動的な処理はあります。

  • 問い合わせAIチャット
  • コメントの読み込みと投稿
  • Turnstile検証
  • Originチェック
  • レート制限
  • D1への保存

これらはCloudflare Pages Functionsへ寄せました。

Astro側に置くのはUIです。APIキー、D1 binding、Turnstile secret、hash salt、Origin判定はブラウザへ出しません。

この方針は、問い合わせAIチャットの技術設計Cloudflareだけで作るブログコメント機能 の両方で同じです。

機能UIAPI境界保存先・外部API
問い合わせAIAstro/api/ai-contactOpenAI API
コメントAstro/api/commentsCloudflare D1
bot対策TurnstilePages Functionsで検証Cloudflare Siteverify
rate limitなしPages Functionsで判定メモリ、D1、必要ならWAF/KV/DO

大事なのは、動的機能を足しても「サイト全体がアプリケーションサーバーになる」わけではないことです。

静的サイトの強みを残し、必要な境界だけをAPI化します。

3. CMSは編集入口、公開判断はPRにする

Sveltia CMSは、静的サイトに編集画面を足すために入れました。

ただし、CMSを入れたからといって、CMSを本番DBのように扱うわけではありません。

Acecoreでは、CMSは日本語sourceを編集する入口です。

  • ブログ記事
  • 著者情報
  • タグ定義
  • 日本語source JSON
  • 画像アップロード

編集結果はGitHub上の差分になります。そこからPR、build、レビューを通してmainへ入れます。

この設計は Sveltia CMS導入ガイド に詳しく書きました。

CMSの役割を「公開DB」ではなく「Git差分を作るUI」と捉えると、静的サイトとの相性がよくなります。

4. 多言語はUI翻訳ではなく静的ページにする

多言語対応は、CMS画面で全言語を直接編集する運用にはしませんでした。

日本語sourceを正として、翻訳はGitHub CopilotのPRに分けています。

理由は単純です。

  • 言語別URLを持てる
  • title、description、OGP、JSON-LDを言語別にできる
  • sitemap、RSS、hreflangに出せる
  • 翻訳差分をレビューできる
  • CMS画面を複雑にしすぎない

この考え方は Sveltia CMSで多言語ブログを運用する方法 にまとめています。

UI上で翻訳できることと、検索エンジンに言語別ページとして渡せることは別です。

だから、翻訳は表示時の処理ではなく、公開前のコンテンツ生成処理として扱います。

5. 問い合わせ導線は会話、CTA、フォームで分ける

問い合わせ周りは、全部をAIに寄せないようにしました。

訪問者の状態によって、適した導線が違うからです。

訪問者の状態使う導線
どのサービスに合うか迷っている問い合わせAI
すでにサービスページを読んだサービスCTA
正式に相談内容を送りたい問い合わせフォーム
LINEで軽く相談したいLINE導線

問い合わせAIは、公開済みサイト情報を使って案内します。個人情報をAIへ渡す場所にはしません。

サービスCTAは、ユーザーが読んでいたサービス文脈をURLパラメータでフォームへ渡します。フォーム側では、問い合わせ種別と件名を初期化します。

この部分は サービスCTAから問い合わせフォームへ文脈を引き継ぐ技術設計 で掘り下げています。

導線を増やすときは、役割を分けることが重要です。

AIチャットもフォームもLINEも、同じ「問い合わせボタン」ではありません。訪問者の迷い方に合わせて配置します。

6. AI出力はHTMLとして信頼しない

問い合わせAIを入れると、次に問題になるのが回答の描画です。

AIが 詳しくは[サービス一覧](/services/)をご覧ください のようなMarkdownを返すなら、リンクとして表示したくなります。

しかし、AI回答をそのまま innerHTML に入れてはいけません。

そこで、AIチャット回答のMarkdownリンク安全描画 では、次の方針にしました。

  • AI回答はテキストとして受け取る
  • 必要なMarkdownだけを小さく拾う
  • URLはtrimしてから許可リストで判定する
  • 許可できるURLだけDOM APIでリンク化する
  • 許可できないURLはテキストとして残す

AI機能をサイトに入れるときは、モデルの精度だけでなく、出力をどう表示するかまで設計対象です。

7. コメント機能はCloudflareだけで閉じる

コメント機能は、外部コメントサービスを使わずに作りました。

これは今回の構成の中でも、特に分かりやすい判断です。

すでにCloudflare Pagesで配信しているなら、軽いコメント機能はCloudflare内で完結できます。

  • Pages FunctionsでGET/POSTを受ける
  • D1にコメントを保存する
  • Turnstileをserver-side validationする
  • Originとhostname allowlistを見る
  • URL、メール、HTML、Markdownリンク、宣伝語句を拒否する
  • previewとproductionでD1を分ける

詳しくは CloudflareだけでAstroブログにコメント機能を作る方法 にまとめています。

コメント欄は便利ですが、荒らされやすい場所でもあります。

だから「コメント機能を足す」ではなく、「どこまで投稿を許すか」「何を検索indexに入れないか」「削除運用をどうするか」を最初に決めます。

8. 検索対象と交流機能を分ける

ブログ本文は検索対象です。

一方、コメントはPagefind対象から外しています。

これは、静的サイトに交流機能を足すときの重要な判断です。

公式サイトの本文はレビュー済みコンテンツです。コメントは訪問者の投稿です。コメント本文まで検索対象やSEO対象にするなら、承認制、静的HTMLへの再生成、moderationが必要になります。

最初の実装では、コメントは交流機能として扱い、検索対象にはしません。

同じように、AIチャットの会話ログもブログ本文ではありません。問い合わせフォームの入力も公開コンテンツではありません。

サイト内にある情報をすべて検索対象にするのではなく、公開コンテンツ、操作UI、ユーザー投稿、管理画面を分けて扱う必要があります。

9. 目的別に読む

全部を一度に読む必要はありません。自分のサイトで足したい機能から入ると、判断しやすくなります。

やりたいこと先に読む記事
ブラウザから記事や画像を更新したいSveltia CMS導入ガイド
多言語ブログを検索対象として出したいSveltia CMSで多言語ブログを運用する方法
AIチャットで訪問者を案内したいAstroサイトに問い合わせAIチャットを組み込む技術設計
AI回答に安全なリンクを出したいAIチャット回答のMarkdownリンクを安全に描画する実装設計
サービスページからフォームへ送客したいサービスCTAから問い合わせフォームへ文脈を引き継ぐ技術設計
外部コメントサービスなしでコメント欄を作りたいCloudflareだけでAstroブログにコメント機能を作る方法

おすすめの導入順

これから同じような構成を他サイトへ入れるなら、実装順はこうです。

  1. 静的ページ、ブログ、RSS、sitemap、OGPをAstroで固める
  2. Sveltia CMSで日本語sourceを編集できるようにする
  3. 多言語ページを静的HTMLとして生成する
  4. AIチャットとサービスCTAで相談導線を整える
  5. AI回答のMarkdownリンクやフォームprefillの安全境界を固める
  6. 必要になってからCloudflare内でコメント機能を足す

最初にCMSと多言語を固めると、後から記事を増やしやすくなります。

問い合わせAIやサービスCTAは、問い合わせ導線を強くしたいタイミングで入れます。

コメント機能は、ブログが読まれ始めてから足すくらいで十分です。

他サイトへ転用するときの最小構成

すべてを一度に入れる必要はありません。

最小構成はこうです。

Astro
  - 静的ページ
  - ブログ
  - RSS / sitemap / OGP

Cloudflare Pages
  - 静的配信
  - preview環境

GitHub
  - PRレビュー
  - build check

次に、必要に応じて足します。

CMSが必要
  -> Sveltia CMS + GitHub backend + CMS PR

多言語が必要
  -> locale別Markdown + 翻訳PR + hreflang

問い合わせ導線を強くしたい
  -> AIチャット + サービスCTA + フォームprefill

交流機能が必要
  -> Pages Functions + D1 + Turnstile + moderation方針

この順番なら、機能を足しても土台を壊しにくいです。

まとめ

Astro + Cloudflareの公式サイトは、静的サイトのままでもかなり機能拡張できます。

重要なのは、すべてを一つの仕組みに押し込まないことです。

Astroは公開HTMLを作る。Cloudflareは配信と小さなAPI境界を受け持つ。Sveltia CMSは日本語sourceを編集する。翻訳はPRで作る。AIチャットは相談導線の整理に使う。コメントはCloudflare内に閉じる。検索対象はレビュー済みコンテンツに絞る。

このようにレイヤーを分けると、公式サイトは単なる会社案内ではなく、更新、翻訳、相談、交流まで扱える運用基盤になります。

このページを入口にすると、必要な機能だけを選びながら、静的サイトの土台を崩さずに拡張できます。

Site Architecture

公式サイトを機能拡張するレイヤー

静的サイトを土台にしつつ、必要な部分だけ動的にしていきます。

配信する

Astroで静的HTMLを生成し、Cloudflare Pagesで配信する。

更新する

Sveltia CMSで日本語sourceを編集し、GitHub PRで確認する。

翻訳する

翻訳はCMS画面ではなく、CopilotのPR運用に分離する。

案内する

問い合わせAIとサービスCTAで、訪問者を適切なフォームへ送る。

受ける

Pages FunctionsでAPI境界を作り、D1やTurnstileを必要な箇所だけ使う。

守る

Markdown描画、Origin、rate limit、noindex、Pagefind対象を分けて制御する。

ただ機能を足す場合と、全体設計として足す場合

機能ごとに足す

  • AI、CMS、コメント、フォームがそれぞれ別の設計思想になる
  • 外部サービスのscriptや管理画面が増え、説明責任が分散する
  • 多言語URL、検索index、preview環境でズレが起きやすい
  • 機能同士の関係が見えず、導入順を決めにくい

レイヤーで足す

  • Astro、Cloudflare、GitHub、OpenAI APIの役割を分けて説明できる
  • 動的APIはPages Functionsに集め、保存先はD1などCloudflare側に寄せられる
  • CMS更新、多言語翻訳、検索、RSS、sitemapを同じコンテンツ構造で扱える
  • 用途別・導入順のインデックスとして読み進めやすい
他サイトへ転用するときの設計チェック
  • 完了: 静的に出せるものと、APIが必要なものを分ける
  • 完了: CMSは編集入口、翻訳はPR、公開判断はbuildに分離する
  • 完了: 問い合わせAIには個人情報を渡さず、公開済み情報だけを案内させる
  • 完了: フォーム導線はURLパラメータで文脈を渡し、受信値は安定した分類にする
  • 完了: コメントなど投稿データはpreviewとproductionでDBを分ける
  • 完了: AI出力やユーザー投稿は、HTMLとして信頼せず許可リストで扱う
よくある質問
どこから導入すべきですか?
まずAstroの静的ページ、ブログ、RSS、sitemap、OGPを固めます。次にCMSと多言語を入れ、相談導線が必要になってからAIチャット、サービスCTA、コメント機能を足す順番が扱いやすいです。
すべてCloudflareだけで作るべきですか?
いいえ。問い合わせAIのようにOpenAI APIを使う部分もあります。ポイントは、配信、API境界、DB、bot対策をCloudflareへ寄せ、外部サービスを入れる場所と入れない場所を意識して分けることです。
小規模サイトでもここまで必要ですか?
最初から全部は不要です。ただ、CMS、問い合わせ導線、多言語、コメントのどれかを足す予定があるなら、URL、データ保存先、preview環境、検索indexの扱いを早めに決めると後から楽になります。

コメント

コメントを読み込んでいます...

URL、メールアドレス、宣伝文は投稿できません。

G

Gui

Acecore 代表。業務システム、Web、DB/インフラ、品質保証、AI活用を、事業課題の整理から設計・導入後の改善までつなげて推進している。 C#/.NET を軸にした実装力を土台に、PHP/JavaScript、SQL Server/PostgreSQL/MySQL、Linux/Windows Server なども踏まえ、要件整理、技術選定、品質基準、GitHubベースの開発運用まで一体で設計する。 生成AIは、開発・検証・情報整理などの業務プロセスに取り入れ、小規模チームでも速く確かな成果を出すための実務基盤として活用している。

事業課題整理技術選定システム設計C#/.NETDB・インフラ設計GitHub開発運用生成AI活用AIワークフロー設計品質設計現場連携

運用・インフラのお悩みはありませんか?

サーバー構築からメール移行、セキュリティ対策まで、安定運用をサポートします。

関連記事

記事を検索