Cloudflare Pages上のバニラ静的サイト
ビルドステップ不要。ファイルを編集 → main にプッシュ → Cloudflare Pagesが自動デプロイ。高速で安価、ツールチェーンと格闘することはありません。
バニラを選ぶ理由(判断基準)
- ビルド/CIの煩わしさゼロ。2行のコピー修正も30秒でデプロイ。
- フレームワークへのロックインや書き換えのコストがありません。「追加、書き換えなし」がルール。
- サイト全体がgrep可能で、デバッグしやすく、直感的。
- トレードオフ: より手動のDOMコードが必要。小〜中規模なら価値があります。
リポジトリ + デプロイ
- 1つのGitHubリポジトリ → Cloudflare Pagesプロジェクト、mainブランチへのプッシュで自動デプロイ。
- Pagesはリポジトリルートを配信。クリーンURL:
/mi-cuenta.htmlは/mi-cuentaで配信されます。 - Functions(サーバーレス)は
/functionsに配置(supabase-backend参照)。
デプロイルーティン(毎回のデプロイで実施)
- ファイルを編集します。
- JSがコンパイルできるか確認 — 壊れたインラインJSをプッシュしないでください。インライン
<script>ブロックを抽出し、それぞれにvm.compileFunctionを実行。.js/.cjsファイルはnode --checkを使用。reference/verify-inline.cjsを参照。 - アセットをキャッシュバストする:
node .claude/cache-bust.cjs— HTML内のassets/**/*.css|js参照すべてに?v=<git-short-hash>をスタンプし、version.jsonを書き込みます。reference/cache-bust.cjsを参照。 - バージョンスタンプを更新(単一の真実源は1つのJSファイルにあり、フッターに控えめに表示)し、ログに記録します。バージョン管理スキームについては
project-continuityを参照。 - コミット(そのプロジェクトの言語で説明的に、共著者トレーラーを付けて)、main にプッシュ。
- ライブ確認:
curlでデプロイされたアセットを取得し、新しいバージョンスタンプと、version.jsonがアセットの?v=と一致することを確認(一致しないと自動リローダーがループします)。Cloudflareのボット対策はプレーンなクローラーをブロックするので、ブラウザのUser-Agentを使用してください。
.claude/は通常gitignoreされるため、キャッシュバスト/確認スクリプトはローカルに残ります(リポジトリではなく、ビルド時に自分のマシンで実行されます)。
キャッシュバスティング + 自動リロード(「表示されない」問題を解消)
2つのレイヤー。どちらも reference/ にあります:
cache-bust.cjs— デプロイのたびにすべてのアセット参照に?v=<git hash>を再スタンプし、ブラウザが変更されたCSS/JSを再取得するようにします。さらにversion.json = {"v":"<hash>"}を書き込みます。- 自動リローダー (
reference/auto-reload.js) — すべてのページに含まれる小さなスクリプトで、自身の読み込まれた?v=を読み取り、/version.json(no-storeで配信)をポーリングし、新しいデプロイを検出すると: タブに戻ったときにリロード(安全なタイミング)、閲覧中はワンタップの「Actualizar」バナーを表示し、入力途中に中断することはありません(window.__noAutoReloadで試験/チェックアウトフローなどをオプトアウト)。ブートストラップの注意点: 初回のみ、ユーザーは一度ハードリフレッシュしてリローダーを読み込みます。以降は自動的になります。
マーカーを常に新鮮に配信するには _headers を使用:
/version.json
Cache-Control: no-store, max-age=0
セキュリティヘッダー(リポジトリルートの _headers)
常に設定: Content-Security-Policy(script-src/frame-src/connect-src を正確なCDN + Supabase URL + リアルタイム用のwssに制限)、X-Frame-Options: DENY、X-Content-Type-Options: nosniff、Referrer-Policy: strict-origin-when-cross-origin、Permissions-Policy、Strict-Transport-Security。実際の注意点: 動画iframeを埋め込むには、プレイヤードメインを frame-src に追加しないと、ブラウザが静かにブロックします。
再利用可能なCSSの慣例
- CSS変数を使ったトークンベースのテーマ設定。
data-theme="dark"の再マップと共有のlocalStorageキーで、テーマがページ/タブ間で同期されます。 - ダークモード: コントラストの確保だけでは不十分。レイヤー階層(bg < surface < card)を明るい段階とシャドウで可視化しないと、フラットに見えます。
white/色はハードコードしないでください。トークンを使ってテーマが応答するようにします。- グローバルな
.btn/.btn-primaryは壊さないでください。スコープ内で上書きします。
このスキルに含まれるファイル
reference/cache-bust.cjs— アセットスタンパ + version.json 書き込みツールreference/auto-reload.js— デプロイ自動リローダー(グローバルに読み込まれるJSファイルに追加)reference/verify-inline.cjs— デプロイ前にインライン<script>ブロックのコンパイルチェックを行うツールreference/headers-example— スターター用の_headers