本文へ移動
SiteKit 無料で始める
目次 中継とホスティング

Docs

中継とホスティング

Cloudflare Pages の中継(Pages Functions)で配信前に値を埋め込む方法と、それ以外のホスティングでの使い方。

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.htmlen
/englishja(接頭辞で始まるだけの別ページは一致しない)
/zh-tw/news/xzh-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 は中継と併用します(フォームと流入元の記録に要ります)。

このページは Markdown でも読めます。AI エージェントには llms.txt(目次)か llms-full.txt(全文)を渡してください。