<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cloudflare on plzhans blog</title><link>https://blog.plzhans.com/ja/tags/cloudflare/</link><description>Recent content in Cloudflare on plzhans blog</description><generator>Hugo</generator><language>ja</language><lastBuildDate>Fri, 11 Sep 2026 13:01:00 +0000</lastBuildDate><atom:link href="https://blog.plzhans.com/ja/tags/cloudflare/index.xml" rel="self" type="application/rss+xml"/><item><title>Cloudflare Workers キャッシュ設定方法 - エッジキャッシュとTiered Cache</title><link>https://blog.plzhans.com/ja/posts/127-cloudflare-workers-cache-tiered-cache/</link><pubDate>Fri, 11 Sep 2026 13:01:00 +0000</pubDate><guid>https://blog.plzhans.com/ja/posts/127-cloudflare-workers-cache-tiered-cache/</guid><description>&lt;p&gt;&lt;picture&gt;&#10; &lt;source srcset="https://blog.plzhans.com/posts/127-cloudflare-workers-cache-tiered-cache/assets/1_3d822a0f-7e83-8170-a661-c0a4f4df8698_hu_3defae76308df863.webp" type="image/webp"&gt;&#10; &lt;img src="https://blog.plzhans.com/posts/127-cloudflare-workers-cache-tiered-cache/assets/1_3d822a0f-7e83-8170-a661-c0a4f4df8698_hu_512a1c1f75bf96a1.png" alt="複数のエッジノードが上位階層の一箇所を経由してオリジンに到達するTiered Cache構成を表した代表画像" width="1200" height="630" loading="eager" fetchpriority="high"&gt;&#10; &lt;/picture&gt;&lt;/p&gt;&#10;&lt;h2 id="概要"&gt;概要&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;この記事は &lt;a href="../124-cloudflare-workers-static-site-guide/"&gt;Cloudflare Workers 静的サイトガイド - デプロイからSEOまで&lt;/a&gt; シリーズの一部です。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Workerが外部APIを呼び始めると、すぐにキャッシュが必要になります。かけなければ&lt;strong&gt;オリジンの負荷がページビューの分だけ増えます。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;かけること自体は1行で済みますが、その後に知らなければ必ず踏む罠がいくつかあります。特に&lt;strong&gt;エッジキャッシュが全世界で共有されない&lt;/strong&gt;という点は、知ってしまえば当然ですが、知らなければ「なぜキャッシュが当たらないのか」としばらく悩むことになります。&lt;/p&gt;&#10;&lt;h3 id="この記事で扱うこと"&gt;この記事で扱うこと&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;キャッシュをかける2つの方法 — &lt;code&gt;fetch()&lt;/code&gt; の &lt;code&gt;cf&lt;/code&gt; オプションとCache API&lt;/li&gt;&#10;&lt;li&gt;エッジキャッシュが&lt;strong&gt;データセンターごとに別&lt;/strong&gt;であることと、その対応&lt;/li&gt;&#10;&lt;li&gt;Tiered Cacheでオリジンへのリクエストを減らす方法・そのとき &lt;code&gt;cache.put()&lt;/code&gt; が使えない理由&lt;/li&gt;&#10;&lt;li&gt;同じURLがヘッダーによって異なるレスポンスを返す場合のキャッシュキーの問題&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="扱わないこと"&gt;扱わないこと&lt;/h3&gt;&#10;&lt;p&gt;Workers Static Assetsの構造とデプロイは &lt;a href="../125-cloudflare-workers-static-assets-routing-billing/"&gt;Cloudflare Workers 静的サイトホスティング - リクエストの流れと課金基準&lt;/a&gt;、ローカル開発は &lt;a href="../126-cloudflare-workers-wrangler-dev-deploy/"&gt;wrangler 使い方 - Cloudflare Workers のローカル開発とデプロイ&lt;/a&gt; にあります。&lt;/p&gt;&#10;&lt;p&gt;KV・R2・D1のようなストレージは範囲外です。この記事は&lt;strong&gt;HTTPレスポンスキャッシュ&lt;/strong&gt;のみを扱います。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="キャッシュをかける2つの方法"&gt;キャッシュをかける2つの方法&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;① &lt;code&gt;fetch()&lt;/code&gt; の &lt;code&gt;cf&lt;/code&gt; オプション&lt;/strong&gt; — レスポンスをCloudflareのエッジキャッシュに任せます（&lt;a href="https://developers.cloudflare.com/workers/runtime-apis/request/" target="_blank" rel="noopener noreferrer"&gt;Request ドキュメント&lt;/a&gt;）。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;cf&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cacheTtl&lt;/span&gt;: &lt;span class="kt"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cacheEverything&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;②&lt;/strong&gt; &lt;a href="https://developers.cloudflare.com/workers/runtime-apis/cache/" target="_blank" rel="noopener noreferrer"&gt;&lt;strong&gt;Cache API&lt;/strong&gt;&lt;/a&gt; — 自分で入れて取り出します。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="知っておくべきこと3つ"&gt;知っておくべきこと3つ&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;エッジキャッシュはデータセンターごとに別です。&lt;/strong&gt; ドキュメントの表現そのままです。&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;The contents of the cache &lt;strong&gt;do not replicate outside of the originating data center.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Cloudflare Workers 静的サイトガイド - デプロイからSEOまで</title><link>https://blog.plzhans.com/ja/posts/124-cloudflare-workers-static-site-guide/</link><pubDate>Fri, 11 Sep 2026 13:01:00 +0000</pubDate><guid>https://blog.plzhans.com/ja/posts/124-cloudflare-workers-static-site-guide/</guid><description>&lt;p&gt;&lt;picture&gt;&#10; &lt;source srcset="https://blog.plzhans.com/posts/124-cloudflare-workers-static-site-guide/assets/1_3d822a0f-7e83-818c-8060-c230fe8eebe7_hu_452fbc316a5a0cdc.webp" type="image/webp"&gt;&#10; &lt;img src="https://blog.plzhans.com/posts/124-cloudflare-workers-static-site-guide/assets/1_3d822a0f-7e83-818c-8060-c230fe8eebe7_hu_a731f7d9f52c36b2.png" alt="Cloudflare Workersのエッジノードを中央に置き、ホスティング・ローカル開発・キャッシュ・SEOの4編がつながるシリーズ代表画像" width="1200" height="630" loading="eager" fetchpriority="high"&gt;&#10; &lt;/picture&gt;&lt;/p&gt;&#10;&lt;h2 id="概要"&gt;概要&lt;/h2&gt;&#10;&lt;p&gt;ReactやVueで作ったSPA、Hugoで生成した静的サイトを、そのままCDNに載せて使うケースが多いです。デプロイが単純で、サーバーがないので運用するものもありません。&lt;/p&gt;&#10;&lt;p&gt;ところが少し経つと、**「レスポンスに手を入れたいのにサーバーがない」**という瞬間が来ます。ページごとに異なるメタタグを入れたいときや、クローラーに本文を見せたいとき、レスポンスヘッダーを一つ付けたいときです。&lt;/p&gt;&#10;&lt;p&gt;Cloudflareを使っているなら、&lt;strong&gt;サーバーを新しく立てずに&lt;/strong&gt;それができます。静的アセットの前にコードを一枚重ねるのです。このシリーズは、その過程を4編に分けて整理したものです。&lt;/p&gt;&#10;&lt;h2 id="読む順序"&gt;読む順序&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;a href="../125-cloudflare-workers-static-assets-routing-billing/"&gt;Cloudflare Workers 静的サイトホスティング - リクエストの流れと課金基準&lt;/a&gt; — 構造とリクエストの流れ。いつWorkerが動き、いつ課金されるのか&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="../126-cloudflare-workers-wrangler-dev-deploy/"&gt;wrangler 使い方 - Cloudflare Workers のローカル開発とデプロイ&lt;/a&gt; — ローカルで立ち上げてデプロイする方法&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="../127-cloudflare-workers-cache-tiered-cache/"&gt;Cloudflare Workers キャッシュ設定方法 - エッジキャッシュとTiered Cache&lt;/a&gt; — 外部APIを呼び始めたなら&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="../128-react-spa-seo-cloudflare-workers-ssr/"&gt;React SPA SEO 改善方法 - Cloudflare WorkersでメタタグからSSRまで&lt;/a&gt; — メタタグの注入からサーバーレンダリングまで&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;1番は概念、2番はツールです。この2つは順番に読む方がよいです。3・4番は必要なときに選んで読めば大丈夫です。&lt;/p&gt;&#10;&lt;h2 id="なぜworkersなのか"&gt;なぜWorkersなのか&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;追加インフラが0です。&lt;/strong&gt; すでにCloudflareがアセットをサービングしているなら、そこにコードを重ねるだけです。デプロイ対象が増えることもなく、落ちたらサイトが落ちるサーバーがもう一つ増えることもありません。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;無料プランで始められます。&lt;/strong&gt; 1日10万リクエストまで無料で、静的アセットのリクエストはそもそも課金対象ではありません。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;エッジで動きます。&lt;/strong&gt; ユーザーに近いデータセンターで実行されるため、オリジンへの往復がありません。&lt;/p&gt;&#10;&lt;p&gt;もちろん万能ではありません。リクエストあたりCPU 10ms（無料プラン）といった制約があるので、重い計算には向きません。その境界がどこにあるのかもシリーズで扱います。&lt;/p&gt;&#10;&lt;h2 id="各編で扱うこと"&gt;各編で扱うこと&lt;/h2&gt;&#10;&lt;h3 id="1編---静的サイトホスティング"&gt;1編 - 静的サイトホスティング&lt;/h3&gt;&#10;&lt;p&gt;Workers Static Assetsとは何か、そして&lt;strong&gt;リクエストがどの順序で流れるのか&lt;/strong&gt;をシーケンス図で整理しました。&lt;/p&gt;&#10;&lt;p&gt;核心は**「アセットがあればWorkerは動かない」**という基本ルールと、それを覆す &lt;code&gt;run_worker_first&lt;/code&gt; です。課金がどこで発生するのかもここで扱います — 静的アセットは無料で、Workerが実行されたリクエストだけがカウントされるので、Workerを通す経路を狭く取ることがそのままコストになります。&lt;/p&gt;&#10;&lt;p&gt;→ &lt;a href="../125-cloudflare-workers-static-assets-routing-billing/"&gt;Cloudflare Workers 静的サイトホスティング - リクエストの流れと課金基準&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="2編---wrangler-使い方"&gt;2編 - wrangler 使い方&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;wrangler&lt;/code&gt; のインストールからデプロイまで。ランタイム依存は増えないということ、Workerコードの&lt;strong&gt;型設定を分離&lt;/strong&gt;すべき理由、そして最も紛らわしいもの一つ。&lt;/p&gt;</description></item><item><title>Cloudflare Workers 静的サイトホスティング - リクエストの流れと課金基準</title><link>https://blog.plzhans.com/ja/posts/125-cloudflare-workers-static-assets-routing-billing/</link><pubDate>Fri, 11 Sep 2026 13:01:00 +0000</pubDate><guid>https://blog.plzhans.com/ja/posts/125-cloudflare-workers-static-assets-routing-billing/</guid><description>&lt;p&gt;&lt;picture&gt;&#10; &lt;source srcset="https://blog.plzhans.com/posts/125-cloudflare-workers-static-assets-routing-billing/assets/1_3d822a0f-7e83-81cf-9f13-e8e4f94cfedf_hu_f57c70ff3e8bd040.webp" type="image/webp"&gt;&#10; &lt;img src="https://blog.plzhans.com/posts/125-cloudflare-workers-static-assets-routing-billing/assets/1_3d822a0f-7e83-81cf-9f13-e8e4f94cfedf_hu_73b5020d9ab7c943.png" alt="入ってきたリクエストがWorkerを経由して出る道と、静的アセットとして直接出る道に分かれる流れを表した代表画像" width="1200" height="630" loading="lazy"&gt;&#10; &lt;/picture&gt;&lt;/p&gt;&#10;&lt;h2 id="概要"&gt;概要&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;この記事は &lt;a href="../124-cloudflare-workers-static-site-guide/"&gt;Cloudflare Workers 静的サイトガイド - デプロイからSEOまで&lt;/a&gt; シリーズの一部です。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;静的サイトをCloudflareに載せる方法として &lt;strong&gt;Workers Static Assets&lt;strong&gt; があります。ビルド成果物（&lt;code&gt;dist/&lt;/code&gt;）をアップロードすると全世界のエッジでサービングされ、必要なら その前に&lt;/strong&gt;コードを一枚重ねることができます。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;静的ホスティングとして使っているうちに「レスポンスを少し直したい」という要求が生まれたとき、サーバーを新しく立てずに解決できる道です。&lt;/p&gt;&#10;&lt;h3 id="この記事で扱うこと"&gt;この記事で扱うこと&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Workers Static Assetsの構造 — アセットとWorkerコードが一単位でデプロイされる&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;リクエストがどの順序で流れるのか&lt;/strong&gt; — いつWorkerが動き、いつ動かないのか（シーケンス図）&lt;/li&gt;&#10;&lt;li&gt;課金がどこで発生するのかと無料プランの制限&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="続きの記事"&gt;続きの記事&lt;/h3&gt;&#10;&lt;p&gt;この記事は&lt;strong&gt;構造とデプロイ&lt;/strong&gt;を扱います。残りは別にあります。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="../126-cloudflare-workers-wrangler-dev-deploy/"&gt;wrangler 使い方 - Cloudflare Workers のローカル開発とデプロイ&lt;/a&gt; — インストール · 型設定 · &lt;code&gt;wrangler dev&lt;/code&gt; · デプロイ&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="../127-cloudflare-workers-cache-tiered-cache/"&gt;Cloudflare Workers キャッシュ設定方法 - エッジキャッシュとTiered Cache&lt;/a&gt; — エッジキャッシュ · Tiered Cache&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="../128-react-spa-seo-cloudflare-workers-ssr/"&gt;React SPA SEO 改善方法 - Cloudflare WorkersでメタタグからSSRまで&lt;/a&gt; — メタタグの注入 · サーバーレンダリング&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;KV・R2・D1のような他のバインディング、Durable Objects、Cron Triggersは範囲外です。&lt;/p&gt;&#10;&lt;h3 id="前提"&gt;前提&lt;/h3&gt;&#10;&lt;p&gt;Cloudflareのアカウントがあり、静的サイトをビルドできること（&lt;code&gt;npm run build&lt;/code&gt; → &lt;code&gt;dist/&lt;/code&gt;）以外に必要な事前知識はありません。&lt;/p&gt;</description></item><item><title>React SPA SEO 改善方法 - Cloudflare WorkersでメタタグからSSRまで</title><link>https://blog.plzhans.com/ja/posts/128-react-spa-seo-cloudflare-workers-ssr/</link><pubDate>Fri, 11 Sep 2026 13:01:00 +0000</pubDate><guid>https://blog.plzhans.com/ja/posts/128-react-spa-seo-cloudflare-workers-ssr/</guid><description>&lt;p&gt;&lt;picture&gt;&#10; &lt;source srcset="https://blog.plzhans.com/posts/128-react-spa-seo-cloudflare-workers-ssr/assets/1_3d822a0f-7e83-8126-8051-dfd669349a3e_hu_a019422e8cbae81c.webp" type="image/webp"&gt;&#10; &lt;img src="https://blog.plzhans.com/posts/128-react-spa-seo-cloudflare-workers-ssr/assets/1_3d822a0f-7e83-8126-8051-dfd669349a3e_hu_22bb2352b55ca59c.png" alt="空だったHTMLがエッジを通りながら埋められ、クローラーがその結果を読む流れを表した代表画像" width="1200" height="630" loading="lazy"&gt;&#10; &lt;/picture&gt;&lt;/p&gt;&#10;&lt;h2 id="概要"&gt;概要&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;この記事は &lt;a href="../124-cloudflare-workers-static-site-guide/"&gt;Cloudflare Workers 静的サイトガイド - デプロイからSEOまで&lt;/a&gt; シリーズの一部です。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Reactで作ったSPAを静的ホスティングに載せて使うケースが多いです。デプロイが単純で、サーバーがないので運用するものもありません。コストもほとんどかかりません。&lt;/p&gt;&#10;&lt;p&gt;ところが検索を気にし始めると、すぐに壁にぶつかります。&lt;strong&gt;サーバーが返す生のHTMLに、検索エンジンが読むものが一つもないから&lt;/strong&gt;です。&lt;/p&gt;&#10;&lt;p&gt;この記事は、その問題を&lt;strong&gt;バックエンドサーバーを新しく立てずに&lt;/strong&gt;Cloudflare Workersだけで解いていった記録です。3つの段階に分けて扱います。後ろに行くほど得られるものが大きく、手間もかかります。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;0段階 — 何もしない。&lt;/strong&gt; 生のHTMLが空の殻です。ほとんどのSPAがここにいます。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;1段階 — Workersでメタを埋める。&lt;/strong&gt; タイトル・説明・OG・構造化データがレスポンスのHTMLに入ります。作業量が少なく効果が明確です。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;2段階 — Workersで本文まで描く。&lt;/strong&gt; 実際の画面をサーバーでレンダリングして入れます。最も手間がかかりますが、クローラーが読む内容ができます。&lt;/p&gt;&#10;&lt;h3 id="この記事で扱うこと"&gt;この記事で扱うこと&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;GoogleがJSをレンダリングするのに、なぜ自分で入れる方がよいのか&lt;/li&gt;&#10;&lt;li&gt;Workersで &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; を埋める方法と、そのときの罠&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;entry-client&lt;/code&gt; / &lt;code&gt;entry-server&lt;/code&gt; の分離と &lt;code&gt;vite build --ssr&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;サーバーが受け取ったデータをブラウザに渡し、APIの往復を増やさない方法&lt;/li&gt;&#10;&lt;li&gt;実際に変わった数値と、踏んだ罠&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="扱わないこと"&gt;扱わないこと&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;各メタ項目を何で埋めるか&lt;/strong&gt; — SEO側のテーマです。SEO最適化の記事を参照&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;wranglerの使い方・リクエストの流れ・デプロイ&lt;/strong&gt; — &lt;a href="../125-cloudflare-workers-static-assets-routing-billing/"&gt;Cloudflare Workers 静的サイトホスティング - リクエストの流れと課金基準&lt;/a&gt; · &lt;a href="../126-cloudflare-workers-wrangler-dev-deploy/"&gt;wrangler 使い方 - Cloudflare Workers のローカル開発とデプロイ&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;エッジキャッシュ・Tiered Cache&lt;/strong&gt; — &lt;a href="../127-cloudflare-workers-cache-tiered-cache/"&gt;Cloudflare Workers キャッシュ設定方法 - エッジキャッシュとTiered Cache&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="前提"&gt;前提&lt;/h3&gt;&#10;&lt;p&gt;Cloudflareに静的サイトを載せたことがあり、&lt;code&gt;wrangler&lt;/code&gt; でローカルにWorkerを立ち上げたことがあると仮定します。初めてなら、上のデプロイの記事を先に読む方がよいです。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="問題--生のhtmlに検索エンジンが読む内容がない"&gt;問題 — 生のHTMLに検索エンジンが読む内容がない&lt;/h2&gt;&#10;&lt;p&gt;ビルドされたSPAのHTMLをそのまま受け取ってみましょう。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl -s https://example.com/products/1234&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ko&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My Service&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;A generic site description&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;root&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;module&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/assets/index-a1b2c3.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;1.6KBほどの殻です。商品名も価格も説明もありません。すべてJSが実行され、APIのレスポンスが届いた後にはじめて作られます。&lt;/p&gt;</description></item><item><title>wrangler 使い方 - Cloudflare Workers のローカル開発とデプロイ</title><link>https://blog.plzhans.com/ja/posts/126-cloudflare-workers-wrangler-dev-deploy/</link><pubDate>Fri, 11 Sep 2026 13:01:00 +0000</pubDate><guid>https://blog.plzhans.com/ja/posts/126-cloudflare-workers-wrangler-dev-deploy/</guid><description>&lt;p&gt;&lt;picture&gt;&#10; &lt;source srcset="https://blog.plzhans.com/posts/126-cloudflare-workers-wrangler-dev-deploy/assets/1_3d822a0f-7e83-81f6-b43f-ee90a3347422_hu_696076b6bfb95313.webp" type="image/webp"&gt;&#10; &lt;img src="https://blog.plzhans.com/posts/126-cloudflare-workers-wrangler-dev-deploy/assets/1_3d822a0f-7e83-81f6-b43f-ee90a3347422_hu_5708cb739124f2fe.png" alt="ローカルで動かしたWorkerランタイムがそのままエッジプラットフォームへ上がっていく過程を表した代表画像" width="1200" height="630" loading="lazy"&gt;&#10; &lt;/picture&gt;&lt;/p&gt;&#10;&lt;h2 id="概要"&gt;概要&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;この記事は &lt;a href="../124-cloudflare-workers-static-site-guide/"&gt;Cloudflare Workers 静的サイトガイド - デプロイからSEOまで&lt;/a&gt; シリーズの一部です。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Cloudflare Workersを扱う仕事は、実質的に&lt;strong&gt;&lt;code&gt;wrangler&lt;/code&gt; を扱う仕事&lt;/strong&gt;です。ローカルで立ち上げるのも、デプロイするのも同じCLIです。&lt;/p&gt;&#10;&lt;p&gt;ところが名前のせいで誤解が一つ生まれます。&lt;strong&gt;&lt;code&gt;wrangler dev&lt;/code&gt; はフロントエンドの開発サーバーではありません。&lt;/strong&gt; 筆者も最初はここでしばらく悩みました。&lt;/p&gt;&#10;&lt;h3 id="この記事で扱うこと"&gt;この記事で扱うこと&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;何をインストールすべきか — そして&lt;strong&gt;ランタイム依存は増えない&lt;/strong&gt;ということ&lt;/li&gt;&#10;&lt;li&gt;Workerコードの&lt;strong&gt;型設定を分離&lt;/strong&gt;すべき理由&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;wrangler dev&lt;/code&gt; が実際に何をするのか · &lt;code&gt;vite dev&lt;/code&gt; との違い&lt;/li&gt;&#10;&lt;li&gt;なぜ&lt;strong&gt;静的サイトのビルドが先&lt;/strong&gt;でなければならないのか&lt;/li&gt;&#10;&lt;li&gt;Workerがレスポンスを直したか確認する方法&lt;/li&gt;&#10;&lt;li&gt;デプロイ — 環境ごとの値の注入 · CIで動かすときの注意点&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="扱わないこと"&gt;扱わないこと&lt;/h3&gt;&#10;&lt;p&gt;Workers Static Assetsの構造とリクエストの流れは &lt;a href="../125-cloudflare-workers-static-assets-routing-billing/"&gt;Cloudflare Workers 静的サイトホスティング - リクエストの流れと課金基準&lt;/a&gt; にあります。&lt;/p&gt;&#10;&lt;h3 id="前提"&gt;前提&lt;/h3&gt;&#10;&lt;p&gt;Cloudflareのアカウントがあり、静的サイトをビルドできること（&lt;code&gt;npm run build&lt;/code&gt; → &lt;code&gt;dist/&lt;/code&gt;）以外に必要な事前知識はありません。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="wrangler-のインストール"&gt;wrangler のインストール&lt;/h2&gt;&#10;&lt;p&gt;CloudflareのCLIです。ローカル実行とデプロイの両方を担当します。コマンド一覧は &lt;a href="https://developers.cloudflare.com/workers/wrangler/commands/" target="_blank" rel="noopener noreferrer"&gt;Commands ドキュメント&lt;/a&gt; にあります。&lt;/p&gt;&#10;&lt;h3 id="インストールしないという選択肢"&gt;インストールしないという選択肢&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;wrangler&lt;/code&gt; は&lt;strong&gt;デプロイツールであってアプリケーションコードではありません。&lt;/strong&gt; そのため依存に入れず、必要なときだけダウンロードして使うこともできます。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# As a devDependency&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;npm i -D wrangler&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;npx wrangler dev&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Or without installing - pin the major version&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;npx wrangler@4 dev&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;pnpm dlx wrangler@4 dev&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;後者の利点は、&lt;strong&gt;ローカルとCIが同じバージョンを使い&lt;/strong&gt;、アプリの &lt;code&gt;package.json&lt;/code&gt; にデプロイツールが入らないことです。欠点は毎回ダウンロードの時間が少しかかることです。&lt;/p&gt;</description></item></channel></rss>