EmDash のブログを Cloudflare の無料プランで公開するまでにやった設定まとめ
EmDash(Astro ベースの CMS)のブログを Cloudflare Workers に置き、独自ドメイン・費用の見張り・AI に見つけてもらうための設定まで、無料プランでやったことを画面つきでまとめました。

このブログ(おきなこ備忘録)は、Cloudflare が作った CMS「EmDash」で動いています。Cloudflare の無料プランのまま、独自ドメインで公開して、費用の見張りと「AI に見つけてもらう」ための設定までやりました。あとで自分が見返せるように、やった設定を画面つきでまとめておきます。料金やプランの条件、画面の見た目は 2026年10月時点のものです。
全体の構成
- CMS: EmDash 1.3(Astro ベース)の
cloudflare:blogテンプレート - 置き場所: Cloudflare Workers(記事は D1、画像は R2、セッションは KV)
- ドメイン: Cloudflare Registrar で取った
okinako.dev - デプロイ: 手元から
npm run deploy(GitHub との自動デプロイ連携はしていない)
1. 独自ドメインだけで配信する

wrangler.jsonc で、workers.dev の URL を無効にして、独自ドメインだけで配信しています。
{
"name": "okinako-blog",
"workers_dev": false,
"preview_urls": false,
"routes": [{ "pattern": "example.com", "custom_domain": true }],
"vars": { "EMDASH_SITE_URL": "https://example.com" }
}- workers.dev の URL には、アカウントのサブドメインが入ります。ブログの名義とアカウントを結び付けたくなかったので、使わないことにしました。
- 同じサイトが2つの URL で見えると、検索エンジンに別のサイトとして扱われることがあります。ページには正式な URL(
canonical)が入っていますが、そもそも1つにしておくほうがすっきりします。 - 管理画面のログイン(パスキー)は独自ドメインに結び付くので、workers.dev からは管理画面に入れません。
- ドメインを取るときの登録者情報は、Cloudflare Registrar の既定で WHOIS には出ません。組織名の欄は空にしておきます。
2. 変数・シークレット・データの置き場所

EMDASH_SITE_URLを固定する: 指定しないと、管理画面の初期設定をした URL がサイトの URL として記録され、管理者のパスキーもその URL に結び付きます。EMDASH_ENCRYPTION_KEY: 本番用にローカルとは別のキーをnpx emdash secrets generateで作り、wrangler secret putで登録しました。なくすとプラグインに保存した秘密情報が読めなくなるので、控えはパスワードマネージャーに置いています。- D1・R2・KV: 初回の
wrangler deployで自動で作られます。ただし R2 だけは、アカウントで一度ダッシュボードから有効にしておく必要がありました。
3. 費用を見張る

- Workers・D1・KV の無料プランは、上限に達するとリクエストが止まるだけで、請求は発生しません。
- R2 だけは、無料枠を超えた分が従量で請求されます。
- 製品ごとの利用量の通知は Pro プラン以上でしか使えないので、代わりに予算アラートを使っています。アカウント全体の従量課金が 1 ドルを超えたらメールが来ます。R2 を有効にしたときに自動で作られた 10 ドルのアラートを、1 ドルに下げました。
4. アクセス解析

Cloudflare Web Analytics を使っています。Cookie を使わない仕組みです。Cloudflare で配信しているサイトなら、自動セットアップで計測用のスクリプトが入ります。
5. AI に見つけてもらうための設定
AI クローラーをブロックしない

AI Crawl Control のセキュリティ画面で、どのクローラーもブロックしていません。ClaudeBot がすでに来て、正常に読めています。
robots.txt で利用を許可する(Content Signals)

Content-Signalで、検索(search)・AI の回答での引用(ai-input)・AI の学習(ai-train)を、すべて許可しています。- コメントで、役に立ったら Ko-fi で応援してほしい、と一言添えています。
- robots.txt は、EmDash の管理画面の SEO 設定で全文を書けます。既定の内容が丸ごと置き換わるので、管理画面を除外する行(
Disallow: /_emdash/)とサイトマップの行も自分で書きます。
更新を検索エンジンに知らせる(Crawler Hints)

Crawler Hints をオンにすると、記事を公開・更新したときに、IndexNow で Bing などに通知されます。ChatGPT の検索や Copilot は Bing の索引も使っているとされるので、AI に早く拾われることを期待しています。オンにすると補足条項に同意したことになります。
AI エージェントには Markdown を返す

Cloudflare の「エージェント用 Markdown」は Pro プラン限定なので、同じことをサイト側で自前で作りました。

- リクエストの
Acceptにtext/markdownがあるか、URL の末尾が.mdなら、HTML の代わりに Markdown を返します。 - 本文は EmDash の
portableTextToMarkdownで変換し、先頭にタイトル・URL・公開日・更新日・要約を付けます。 - HTML 側には
<link rel="alternate" type="text/markdown">で Markdown 版の場所を書き、Vary: Acceptも付けます(キャッシュで HTML と取り違えないように)。
記事ページ(Astro)の先頭で、次のように分岐しています(要点だけ)。
import { portableTextToMarkdown } from "emdash/client";
const wantsMarkdown =
Astro.url.pathname.endsWith(".md") ||
(Astro.request.headers.get("accept") ?? "").includes("text/markdown");
if (wantsMarkdown) {
const body = portableTextToMarkdown(post.data.content);
return new Response(`# ${post.data.title}\n\n${body}`, {
headers: { "Content-Type": "text/markdown; charset=utf-8", Vary: "Accept" },
});
}
// HTML を返すときも、同じ URL で中身が変わることをキャッシュに伝える
Astro.response.headers.set("Vary", "Accept");診断で確かめる

エージェントの準備状況の診断では、レベル 1「すぐに実行できる改善」が 5/5 完了になりました。レベル 2 以降(API の一覧、AI 向けのログイン手順、コマースなど)は、サービスを提供するサイト向けなので、ブログでは対応していません。
6. EmDash 側でやったこと
- 初期設定: サンプル記事は入れずに「Empty site」で始める(英語のダミー記事が公開されないように)。管理者はパスキーで登録する。
- コメント: 既定は
first_timeで、初めてコメントする人の投稿だけが承認待ちになります(承認済みの人は次から即公開)。全件を承認制にしたいならallにします。 - 日本語向けの調整:
<html lang="ja">と、文節での折り返し(word-break: auto-phraseなど)をサイト全体に当てる(折り返しの記事)- 日付を日本語の書式・日本時間で表示する(Workers は UTC で動くため)
- 読了時間を「分」表記にする
- コードブロックの色付け: Astro に入っている Shiki で色を付け、
light-dark()でライト/ダークに追従させる。 - Ko-fi のボタン: 公式のボタン画像をサイトに置いて配信する(外部のスクリプトを読み込まない)。

Discussion
No comments yet