2つのやり方
CMS の値を HTML に入れるやり方は2つあります。フォームと流入元の記録は、どちらでも script だけで動きます。
| Cloudflare Pages の中継(おすすめ) | data-embed(ほかのホスティング) | |
|---|---|---|
| 値が入るとき | 配信の前(サーバー側) | 表示されたあと(ブラウザ側) |
| 検索エンジン・JavaScript 無効の人 | 値の入ったページが届く | 静的な文言が拾われることがある |
| 表示のチラつき | 無い | 一瞬、静的な文言が見える |
記事ごとのページ・タグページ・記事の url | 使える | 使えない |
| 管理画面の GTM ID の差し込み | 使える | 使えない(data-gtm を使う) |
Cloudflare Pages の中継
置くファイル
サイトの functions/ に中継のファイルを2つ置きます。
functions/_middleware.ts
functions/_cms/render.ts_cms/render.tsは生成物です。編集しません(編集すると、更新のときに食い違います)- 外部向けの配布の手段(ダウンロード・CLI)は準備中です 近日
環境変数
Pages プロジェクトの vars(wrangler.jsonc か Cloudflare のダッシュボード)で設定します。
| 変数 | 必須 | 説明 |
|---|---|---|
CMS_SITE | 必須 | サイト ID |
CMS_ORIGIN | 必須 | https://cdn.sitekit.example(末尾のスラッシュは不要) |
CMS_LOCALES | 言語:接頭辞 のカンマ区切り。省略すると ja:/ | |
CMS_NEWS_PATH | 記事ページのパス兼コレクションのキー。省略すると news | |
CMS_INDEXABLE_HOSTS | 検索に載せてよいホスト名のカンマ区切り。省略すると何もしない |
CMS_SITE か CMS_ORIGIN が無いと、中継は何もせず静的な HTML をそのまま返します。
{
"name": "hanaya",
"compatibility_date": "2026-08-01",
"pages_build_output_dir": "public",
"vars": {
"CMS_SITE": "hanaya",
"CMS_ORIGIN": "https://cdn.sitekit.example",
"CMS_LOCALES": "ja:/,en:/en",
"CMS_NEWS_PATH": "news"
}
}言語の判定
CMS_LOCALES は ja:/,en:/en,zh-tw:/zh-tw のように書きます。先頭が主言語です。パスの最長一致で言語が決まります。
| パス | 言語 |
|---|---|
/, /about/ | ja(知らないパスもここに落ちる) |
/en, /en/, /en/about, /en.html | en |
/english | ja(接頭辞で始まるだけの別ページは一致しない) |
/zh-tw/news/x | zh-tw |
Accept-Language は見ません。同じ URL は誰が見ても同じ言語です。
検索避け(CMS_INDEXABLE_HOSTS)
プレビュー用のホスト(*.pages.dev など)と本番のホストで同じ中身を配ると、重複したページとして扱われ、プレビューのほうが検索結果に出ることがあります。CMS_INDEXABLE_HOSTS に本番のホストだけを書くと、それ以外のホストで返す HTML に X-Robots-Tag: noindex が付きます。
"CMS_INDEXABLE_HOSTS": "www.example.jp,example.jp"| 値 | 意味 |
|---|---|
| 未設定・空 | 何もしない |
www.example.jp,example.jp | この2つ以外のホストの HTML に noindex |
- | どのホストも検索に載せない(本番のドメインがまだ無いとき) |
- 完全一致です(
www.example.jpを書いてもa.www.example.jpは許可されない)。大文字・小文字は区別しません - 付くのは HTML だけです(画像や CSS には付けない)
- サイト側が
_headersなどでX-Robots-Tagを出している場合は上書きしません
反映までの時間
公開 JSON は 60 秒キャッシュされ、中継が返す HTML も max-age=60 です。お店の人が「公開」を押してから最長1分で全ページに反映されます。サイトの再デプロイは要りません。
CMS が止まっているとき
静的な HTML をそのまま返します。 取得の失敗・タイムアウト(5秒)・壊れた JSON のどれでも、埋め込みをしなかったページを返すだけで、サイトは止まりません。
例外は記事ページだけです。取得に成功したうえで ID が見つからないときは 404 を返します。取得できなかったときは雛形をそのまま返します。
動いているかの確かめ方
中継が値を埋め込むと、レスポンスヘッダに x-sitekit-rendered: 1 が付きます。GET で確かめます。curl -I(HEAD)では付きません。
curl -sD - -o /dev/null https://example.com/ | grep -i sitekit
curl -s https://example.com/ | grep -o 'data-sk-rendered="1"'付いていなければ、環境変数の設定漏れか、CMS に届いていないか、そのページが HTML(200)ではありません。
ほかのホスティング(data-embed)
Cloudflare Pages 以外(関数を動かせない静的ホスティングなど)では、script に data-embed を付けます。
<script src="https://cdn.sitekit.example/sitekit.js" data-site="hanaya" data-embed defer></script>- 表示のあとに公開 JSON を取得して、
data-cms系の印に値を入れます document.bodyの中身を丸ごと置き換えます。 body の要素に付けたイベントは消えます(フォームは自動で付け直します)。サイト独自の JavaScript がある場合は避けてください- 取得に失敗したときは何もしません。静的な HTML が残ります
- 記事ごとのページ(
/news/<id>)・タグページ・記事のurlは中継の機能なので使えません
中継を使うサイトでは
data-embedを付けません。 埋め込みは2回実行できません(1回目の値を2回目が上書きします)。中継済みのページにはdata-sk-rendered="1"が付いていて script 側は何もしませんが、そもそも併用しないでください。data-embedの無い script は中継と併用します(フォームと流入元の記録に要ります)。