[{"data":1,"prerenderedAt":1122},["ShallowReactive",2],{"content-/cloudflare-pages-to-workers-static-assets":3,"all-pages-for-dir":1120,"og-image-/cloudflare-pages-to-workers-static-assets":1121},{"id":4,"title":5,"body":6,"category":1101,"description":1102,"extension":1103,"meta":1104,"navigation":1105,"ogImage":1101,"path":1106,"project_name":1101,"published":1107,"publishedAt":1108,"seo":1109,"stem":1110,"tags":1111,"todo":1101,"unpublished":1107,"updatedAt":1101,"__hash__":1119},"pages/2026-06/2026-06-29/cloudflare-pages-to-workers-static-assets.md","Cloudflare Pages はもう Workers の中に住んでいる ― Static Assets 統合後の地図",{"type":7,"value":8,"toc":1085},"minimark",[9,13,30,38,41,79,84,91,94,126,129,141,145,148,170,177,180,183,215,222,226,236,243,252,265,277,324,346,351,354,439,449,463,473,483,487,494,521,524,528,534,538,544,708,725,732,736,742,921,938,947,953,967,974,978,981,995,1002,1005,1008,1043,1050,1053,1081],[10,11,12],"p",{},"無料でエッジに静的サイトを撒けるのが気持ちよくて Cloudflare Pages を愛用してきた。最近のタイムラインで「Workers の Static Assets を使ったほうがいい」と書かれているのを何度か見かけて、引用元のポストもまさにそれだった。",[14,15,16,19],"blockquote",{},[10,17,18],{},"Cloudflare Workersのstatic assetsを使えば100万アクセス/月あっても0円なのでオススメです",[10,20,21],{},[22,23,29],"a",{"href":24,"target":25,"rel":26},"https://x.com/catnose99/status/1938511604770619886","_blank",[27,28],"noopener","noreferrer","→ 元ポスト（@catnose99, 2026-06-27）",[10,31,32,33,37],{},"自分も ",[34,35,36],"code",{},"wrangler"," を叩いてデプロイしているし、なんとなく Pages を使っている気がしているが、ワーカーズの中にページズが入っているのかいないのか、結局どっちで動いているのか、毎回曖昧なまま済ませてきた。",[10,39,40],{},"ここで一度きちんと整理する。結論を先に出す。",[42,43,44,52,58,64],"ul",{},[45,46,47,51],"li",{},[48,49,50],"strong",{},"Cloudflare Pages は廃止されない","。ただし新機能は Workers にしか乗らなくなった",[45,53,54,57],{},[48,55,56],{},"Workers に Static Assets が組み込まれ","、「実質 Pages」と同じことが Workers の上でできるようになった",[45,59,60,63],{},[48,61,62],{},"静的アセットのリクエストは Pages も Workers も無料・無制限","。違うのは Functions / Worker code を呼んだ時の課金枠の数え方",[45,65,66,67,70,71,74,75,78],{},"自分の 2 プロジェクトのうち、",[48,68,69],{},"mdx-playground は完全 SSG だから移行しなくても無料","。",[48,72,73],{},"eurekapu-nuxt4 は SSR が混じる","ので Functions 課金枠が走るが、",[34,76,77],{},"_routes.json"," の exclude を入れてあるので静的アセット分は Functions を経由していない。Workers に移しても同じ最適化が効く",[80,81,83],"h2",{"id":82},"before-after-の地図","Before / After の地図",[10,85,86],{},[87,88],"img",{"alt":89,"src":90},"Cloudflare Pages と Workers + Static Assets の構成比較","/images/cloudflare-pages-to-workers-static-assets/figure-01-before-after.svg",[10,92,93],{},"左が従来の Pages、右が Workers + Static Assets の構成。図の見どころは 3 つだけだ。",[95,96,97,103,120],"ol",{},[45,98,99,102],{},[48,100,101],{},"どちらも「静的アセット」と「Worker（＝SSR/API）」の組み合わせ","でできている。製品名が違うだけで、中身は同じ部品",[45,104,105,111,112,115,116,119],{},[48,106,107,108,110],{},"Pages は ",[34,109,77],{}," で「Functions を通す URL / 通さない URL」を仕分ける","。Workers は逆に",[48,113,114],{},"既定で静的アセットが優先","され、必要な URL だけ ",[34,117,118],{},"run_worker_first"," で Worker を先に呼ぶ",[45,121,122,125],{},[48,123,124],{},"無料枠の境目は同じ","。静的アセットへのリクエストはどちらも無制限・無料。課金枠を消費するのは Worker コードを呼んだ時だけ",[10,127,128],{},"つまり「Pages の上に Functions（＝ Worker）が乗っている」のと「Workers の中に Static Assets が同梱されている」のは、責任の所在を反転させただけで、構成図としてはほぼ同じになる。",[10,130,131,132,137,138,70],{},"Cloudflare の Workers チームリードである Kenton Varda が「Pages 固有の機能を一般的な Workers の機能に変換している」と発言していて",[22,133,136],{"href":134,"target":25,"rel":135},"https://cogley.jp/articles/cloudflare-pages-to-workers-migration",[27,28],"（→ Cloudflare Pages vs Workers 2026 / cogley.jp）","、これが現状を一番うまく要約している。Pages は殺されるのではなく、",[48,139,140],{},"Workers の中に吸収されつつある",[80,142,144],{"id":143},"廃止されるではなく飲み込まれる","「廃止される」ではなく「飲み込まれる」",[10,146,147],{},"廃止と統合は意味が違うので、分けて書く。",[42,149,150,157,163],{},[45,151,152,153,156],{},"既存の Pages プロジェクトは",[48,154,155],{},"当面そのまま動き続ける","。マイグレーション期限はまだ発表されていない",[45,158,159,160],{},"ただし、新機能（Durable Objects、Cron Triggers、Queues、Workflows、Tail Workers、Smart Placement など）は",[48,161,162],{},"最初から Workers にしか乗らない",[45,164,165,166,169],{},"そのため、いま新規プロジェクトを始めるなら",[48,167,168],{},"最初から Workers + Static Assets"," を選ぶのが推奨経路になる",[10,171,172,173,176],{},"ここを誤解して「Pages はもう使えない」と書くと言い過ぎになる。逆に「Pages のままでもいい」と書くと、新機能が必要になった瞬間に詰む。",[48,174,175],{},"いまは「動いてるものは動かしておけ、新しく作るなら Workers で」が落としどころ","になっている。",[80,178,179],{"id":179},"無料枠の現在地",[10,181,182],{},"「無料」の話が曖昧になりがちなので、自分が触る範囲だけ整理する。",[42,184,185,195,209],{},[45,186,187,190,191,194],{},[48,188,189],{},"静的アセット","：Pages、Workers どちらも ",[48,192,193],{},"リクエスト数も帯域も無制限・無料","。これが catnose 氏のポストで「100 万アクセス / 月でも 0 円」と書かれている根拠",[45,196,197,200,201,204,205,208],{},[48,198,199],{},"Worker code（＝ SSR / API）","：Free プランで ",[48,202,203],{},"10 万 req / 日","、Paid（$5 / 月）で ",[48,206,207],{},"1000 万 req / 月"," が基本枠",[45,210,211,214],{},[48,212,213],{},"転送量","：Cloudflare は egress を課金しない（これは Pages 時代から）",[10,216,217,218,221],{},"つまり「サーバー処理が要らない静的サイト」は何アクセスあろうが完全無料、というのが Cloudflare 流のオフロード設計だ。自分の mdx-playground は ",[48,219,220],{},"1000 本超の記事を SSG で全部 HTML 化","しているので、ここの無料枠にきれいに乗っている。",[80,223,225],{"id":224},"課金の単位はファイルサイズではなくisolate-を起こした回数","課金の単位は「ファイルサイズ」ではなく「isolate を起こした回数」",[10,227,228,229,231,232,235],{},"ここまで読んで「画像 1 枚を返すだけで Worker invocation 課金枠が走るって、Cloudflare の中で何がそんなに起きているのか」が腹落ちしないと、",[34,230,77],{}," の ",[34,233,234],{},"exclude"," を入れる動機もぼんやりする。中で何が起きているかを切り分けて書く。",[10,237,238,239,242],{},"Cloudflare の各 PoP（世界 300 拠点ほど）にはリクエストを受けたあとの分岐が",[48,240,241],{},"物理的に 2 本","ある。",[10,244,245,248,249,70],{},[48,246,247],{},"(A) 静的アセット配信レーン","\nCloudflare の内部分散ストレージから、ファイルのバイト列をそのまま返す。実装は Cloudflare ネイティブの C++/Rust の HTTP サーバで、リクエストごとに JS ランタイムを起こさない。",[48,250,251],{},"ここを通る分には Worker invocation はゼロ",[10,253,254,257,258,261,262,70],{},[48,255,256],{},"(B) Worker レーン","\nV8 isolate（Chrome の JS エンジンを軽量隔離したコンテナ）をスピンアップして、自分の書いた ",[34,259,260],{},"export default { fetch(req, env) { ... } }"," を実行する。レスポンスは isolate が組み立てて返す。",[48,263,264],{},"この isolate が一度起動したら invocation 1",[10,266,267,268,231,270,273,274,276],{},"Pages では、リクエストがエッジに着くとまず ",[34,269,77],{},[34,271,272],{},"include"," / ",[34,275,234],{}," を見て、「この URL は (A) か (B) か」を決める。",[278,279,284],"pre",{"className":280,"code":281,"language":282,"meta":283,"style":283},"language-jsonc shiki shiki-themes vitesse-light vitesse-light","{\n  \"version\": 1,\n  \"include\": [\"/*\"],         // 既定: 全部 (B) Worker レーン\n  \"exclude\": [\"/_nuxt/*\", \"/images/*\"]   // ここだけ (A) 静的レーン\n}\n","jsonc","",[34,285,286,294,300,309,318],{"__ignoreMap":283},[287,288,291],"span",{"class":289,"line":290},"line",1,[287,292,293],{},"{\n",[287,295,297],{"class":289,"line":296},2,[287,298,299],{},"  \"version\": 1,\n",[287,301,303,306],{"class":289,"line":302},3,[287,304,305],{},"  \"include\": [\"/*\"],",[287,307,308],{},"         // 既定: 全部 (B) Worker レーン\n",[287,310,312,315],{"class":289,"line":311},4,[287,313,314],{},"  \"exclude\": [\"/_nuxt/*\", \"/images/*\"]",[287,316,317],{},"   // ここだけ (A) 静的レーン\n",[287,319,321],{"class":289,"line":320},5,[287,322,323],{},"}\n",[10,325,326,327,330,331,333,334,337,338,341,342,345],{},"eurekapu-nuxt4 の ",[34,328,329],{},"nuxt.config.ts"," で ",[34,332,77],{}," の exclude に ",[34,335,336],{},"/images/*"," と ",[34,339,340],{},"/_nuxt/*"," を入れているのは、まさにこの分岐を Edge に教えるためのもので、入れ忘れると画像も CSS も JS も",[48,343,344],{},"全部 Worker レーン経由","になる。",[347,348,350],"h3",{"id":349},"画像-1-枚で課金される理由","画像 1 枚で課金される理由",[10,352,353],{},"Worker レーンに入ったときに、Nuxt SSR が画像を返す経路で実行されるコードは、結局のところ次の 1 行に近い。",[278,355,359],{"className":356,"code":357,"language":358,"meta":283,"style":283},"language-ts shiki shiki-themes vitesse-light vitesse-light","export default {\n  async fetch(request, env) {\n    return env.ASSETS.fetch(request);  // 内部の静的ストレージを叩いて画像を返すだけ\n  }\n}\n","ts",[34,360,361,374,400,430,435],{"__ignoreMap":283},[287,362,363,367,370],{"class":289,"line":290},[287,364,366],{"class":365},"sHkkW","export",[287,368,369],{"class":365}," default",[287,371,373],{"class":372},"shFtX"," {\n",[287,375,376,380,384,387,391,394,397],{"class":289,"line":296},[287,377,379],{"class":378},"stQ0i","  async",[287,381,383],{"class":382},"senZ8"," fetch",[287,385,386],{"class":372},"(",[287,388,390],{"class":389},"s4oTP","request",[287,392,393],{"class":372},", ",[287,395,396],{"class":389},"env",[287,398,399],{"class":372},") {\n",[287,401,402,405,408,411,414,416,419,421,423,426],{"class":289,"line":302},[287,403,404],{"class":365},"    return",[287,406,407],{"class":389}," env",[287,409,410],{"class":372},".",[287,412,413],{"class":389},"ASSETS",[287,415,410],{"class":372},[287,417,418],{"class":382},"fetch",[287,420,386],{"class":372},[287,422,390],{"class":389},[287,424,425],{"class":372},");  ",[287,427,429],{"class":428},"sxvE3","// 内部の静的ストレージを叩いて画像を返すだけ\n",[287,431,432],{"class":289,"line":311},[287,433,434],{"class":372},"  }\n",[287,436,437],{"class":289,"line":320},[287,438,323],{"class":372},[10,440,441,444,445,448],{},[34,442,443],{},"ASSETS.fetch(...)"," は内部で (A) の静的ストレージを叩きに行くので、",[48,446,447],{},"転送量は egress 無料、画像のバイト数も無料","。それでもエッジは",[95,450,451,454,457,460],{},[45,452,453],{},"V8 isolate を起こす",[45,455,456],{},"fetch handler を呼ぶ",[45,458,459],{},"レスポンスをストリームに書き戻す",[45,461,462],{},"isolate を解放する",[10,464,465,466,469,470,70],{},"を必ず通る。Cloudflare の課金体系は、",[48,467,468],{},"この一連を「Worker invocation 1」とカウント","する。中身が画像か API か SSR か、CPU をどれだけ食ったかは別の枠（CPU time）で計測されるが、",[48,471,472],{},"invocation カウントは「isolate を呼んだか / 呼ばなかったか」だけで決まる",[10,474,475,476,479,480,482],{},"つまり、画像本体のバイト数ではなく、",[48,477,478],{},"画像を返すために isolate を 1 回起こした事実","そのものが課金単位になる。1000 アクセスで画像 30 枚を Worker レーン経由で返したら、invocation が 30,000 回分溶ける。",[34,481,234],{}," を入れて画像 URL を (A) に逃がすと、Edge は「この URL は isolate を起こさないでいい」と判断するので 0 のまま。",[347,484,486],{"id":485},"workers-static-assets-で既定が逆になっている理由","Workers + Static Assets で既定が逆になっている理由",[10,488,489,490,493],{},"このカラクリがわかると、Workers + Static Assets で",[48,491,492],{},"既定の振り分けが逆","になっている理由も自然に読める。",[42,495,496,509],{},[45,497,498,501,502,505,506,508],{},[48,499,500],{},"Pages",": ",[34,503,504],{},"include: ['/*']"," が既定 → 既定が (B) Worker レーン → 静的にしたい URL を ",[34,507,234],{}," で外す",[45,510,511,514,515,517,518],{},[48,512,513],{},"Workers",": 静的アセット配信が既定 → 既定が (A) 静的レーン → Worker を走らせたい URL を ",[34,516,118],{}," で",[48,519,520],{},"指名する",[10,522,523],{},"Cloudflare 自身が「Pages の既定は安全側じゃなかった（うっかり全 URL を Worker 経由にすると課金枠を無駄に食う）」と認めて、Workers + Static Assets ではデフォルトを反転させた。これが Pages → Workers 統合の背景にある実務的な動機の 1 つになっている。",[80,525,527],{"id":526},"自分の-2-プロジェクトはどうなっているか","自分の 2 プロジェクトはどうなっているか",[10,529,530],{},[87,531],{"alt":532,"src":533},"自分の2プロジェクトの現状","/images/cloudflare-pages-to-workers-static-assets/figure-02-my-projects.svg",[347,535,537],{"id":536},"mdx-playgroundlogeurekapucom","mdx-playground（log.eurekapu.com）",[10,539,540,543],{},[34,541,542],{},"apps/web/nuxt.config.ts"," の Nitro 設定はこうなっている。",[278,545,547],{"className":356,"code":546,"language":358,"meta":283,"style":283},"nitro: {\n  preset: \"cloudflare-pages-static\",\n  prerender: {\n    crawlLinks: true,\n    routes: ['/blog', '/', '/beat-monitoring', '/memory-makers'],\n    ignore: [/\\?/, '/search', ...],\n    failOnError: false,\n  },\n},\n",[34,548,549,559,580,589,601,651,683,696,702],{"__ignoreMap":283},[287,550,551,554,557],{"class":289,"line":290},[287,552,553],{"class":382},"nitro",[287,555,556],{"class":372},":",[287,558,373],{"class":372},[287,560,561,564,566,570,574,577],{"class":289,"line":296},[287,562,563],{"class":382},"  preset",[287,565,556],{"class":372},[287,567,569],{"class":568},"sMJiu"," \"",[287,571,573],{"class":572},"sdGka","cloudflare-pages-static",[287,575,576],{"class":568},"\"",[287,578,579],{"class":372},",\n",[287,581,582,585,587],{"class":289,"line":302},[287,583,584],{"class":382},"  prerender",[287,586,556],{"class":372},[287,588,373],{"class":372},[287,590,591,594,596,599],{"class":289,"line":311},[287,592,593],{"class":382},"    crawlLinks",[287,595,556],{"class":372},[287,597,598],{"class":365}," true",[287,600,579],{"class":372},[287,602,603,606,608,611,614,617,619,622,625,628,630,632,634,637,639,641,643,646,648],{"class":289,"line":320},[287,604,605],{"class":382},"    routes",[287,607,556],{"class":372},[287,609,610],{"class":372}," [",[287,612,613],{"class":568},"'",[287,615,616],{"class":572},"/blog",[287,618,613],{"class":568},[287,620,621],{"class":372},",",[287,623,624],{"class":568}," '",[287,626,627],{"class":572},"/",[287,629,613],{"class":568},[287,631,621],{"class":372},[287,633,624],{"class":568},[287,635,636],{"class":572},"/beat-monitoring",[287,638,613],{"class":568},[287,640,621],{"class":372},[287,642,624],{"class":568},[287,644,645],{"class":572},"/memory-makers",[287,647,613],{"class":568},[287,649,650],{"class":372},"],\n",[287,652,654,657,659,661,663,667,669,671,673,676,678,680],{"class":289,"line":653},6,[287,655,656],{"class":382},"    ignore",[287,658,556],{"class":372},[287,660,610],{"class":372},[287,662,627],{"class":568},[287,664,666],{"class":665},"svWSF","\\?",[287,668,627],{"class":568},[287,670,621],{"class":372},[287,672,624],{"class":568},[287,674,675],{"class":572},"/search",[287,677,613],{"class":568},[287,679,621],{"class":372},[287,681,682],{"class":372}," ...],\n",[287,684,686,689,691,694],{"class":289,"line":685},7,[287,687,688],{"class":382},"    failOnError",[287,690,556],{"class":372},[287,692,693],{"class":365}," false",[287,695,579],{"class":372},[287,697,699],{"class":289,"line":698},8,[287,700,701],{"class":372},"  },\n",[287,703,705],{"class":289,"line":704},9,[287,706,707],{"class":372},"},\n",[10,709,710,712,713,716,717,720,721,724],{},[34,711,573],{}," は ",[48,714,715],{},"Pages のうち「静的アセットだけ」を使うプリセット","。Functions は一切作られず、",[34,718,719],{},"dist/"," には HTML / CSS / 画像しか入らない。動的処理は ",[34,722,723],{},"_redirects"," の単純な URL 書き換えだけで、それも Cloudflare の Pages 側で評価される（コンテナを起こさない）。",[10,726,727,728,731],{},"ということは、Worker code が呼ばれる回数は実質ゼロで、無料枠も消費していない。",[48,729,730],{},"Workers + Static Assets に移しても挙動も料金も変わらない","から、急いで移行する理由はない。新しいブログを作るときに最初から Workers preset を選べばいい、くらいの優先度になる。",[347,733,735],{"id":734},"eurekapu-nuxt4info-accountingcom","eurekapu-nuxt4（info-accounting.com）",[10,737,738,739,741],{},"こっちは認証あり・Stripe あり・D1 ありの本格的なアプリで、",[34,740,329],{}," がこうなっている。",[278,743,745],{"className":356,"code":744,"language":358,"meta":283,"style":283},"nitro: {\n  preset: 'cloudflare_pages',\n  sourceMap: false,\n  cloudflare: {\n    pages: {\n      routes: {\n        include: ['/*'],\n        exclude: [\n          '/_nuxt/*',\n          '/images/*',\n          '/favicon.ico',\n          '/robots.txt',\n          ...redirectExcludes,\n        ],\n      },\n    },\n  },\n},\n",[34,746,747,755,770,781,790,799,808,826,836,847,858,870,882,893,899,905,911,916],{"__ignoreMap":283},[287,748,749,751,753],{"class":289,"line":290},[287,750,553],{"class":382},[287,752,556],{"class":372},[287,754,373],{"class":372},[287,756,757,759,761,763,766,768],{"class":289,"line":296},[287,758,563],{"class":382},[287,760,556],{"class":372},[287,762,624],{"class":568},[287,764,765],{"class":572},"cloudflare_pages",[287,767,613],{"class":568},[287,769,579],{"class":372},[287,771,772,775,777,779],{"class":289,"line":302},[287,773,774],{"class":382},"  sourceMap",[287,776,556],{"class":372},[287,778,693],{"class":365},[287,780,579],{"class":372},[287,782,783,786,788],{"class":289,"line":311},[287,784,785],{"class":382},"  cloudflare",[287,787,556],{"class":372},[287,789,373],{"class":372},[287,791,792,795,797],{"class":289,"line":320},[287,793,794],{"class":382},"    pages",[287,796,556],{"class":372},[287,798,373],{"class":372},[287,800,801,804,806],{"class":289,"line":653},[287,802,803],{"class":382},"      routes",[287,805,556],{"class":372},[287,807,373],{"class":372},[287,809,810,813,815,817,819,822,824],{"class":289,"line":685},[287,811,812],{"class":382},"        include",[287,814,556],{"class":372},[287,816,610],{"class":372},[287,818,613],{"class":568},[287,820,821],{"class":572},"/*",[287,823,613],{"class":568},[287,825,650],{"class":372},[287,827,828,831,833],{"class":289,"line":698},[287,829,830],{"class":382},"        exclude",[287,832,556],{"class":372},[287,834,835],{"class":372}," [\n",[287,837,838,841,843,845],{"class":289,"line":704},[287,839,840],{"class":568},"          '",[287,842,340],{"class":572},[287,844,613],{"class":568},[287,846,579],{"class":372},[287,848,850,852,854,856],{"class":289,"line":849},10,[287,851,840],{"class":568},[287,853,336],{"class":572},[287,855,613],{"class":568},[287,857,579],{"class":372},[287,859,861,863,866,868],{"class":289,"line":860},11,[287,862,840],{"class":568},[287,864,865],{"class":572},"/favicon.ico",[287,867,613],{"class":568},[287,869,579],{"class":372},[287,871,873,875,878,880],{"class":289,"line":872},12,[287,874,840],{"class":568},[287,876,877],{"class":572},"/robots.txt",[287,879,613],{"class":568},[287,881,579],{"class":372},[287,883,885,888,891],{"class":289,"line":884},13,[287,886,887],{"class":372},"          ...",[287,889,890],{"class":389},"redirectExcludes",[287,892,579],{"class":372},[287,894,896],{"class":289,"line":895},14,[287,897,898],{"class":372},"        ],\n",[287,900,902],{"class":289,"line":901},15,[287,903,904],{"class":372},"      },\n",[287,906,908],{"class":289,"line":907},16,[287,909,910],{"class":372},"    },\n",[287,912,914],{"class":289,"line":913},17,[287,915,701],{"class":372},[287,917,919],{"class":289,"line":918},18,[287,920,707],{"class":372},[10,922,923,925,926,231,928,930,931,337,934,937],{},[34,924,765],{}," は SSR 込みの Pages プリセット。",[34,927,77],{},[34,929,234],{}," で「",[34,932,933],{},"_nuxt/*",[34,935,936],{},"images/*"," は Pages Functions を通さない（＝静的アセットとして直接配信する）」と明示している。",[10,939,940,941,943,944,946],{},"この ",[34,942,234],{}," を入れた理由がまさに今回の話と地続きで、何も指定しないと「全 URL が Pages Functions（= Worker）経由」になってしまい、画像 1 枚配るだけで Worker invocation 課金枠を消費する。",[34,945,77],{}," の exclude で「静的でいいものは静的に流す」と切り分けることで、無料枠を温存できる。",[10,948,949,950,70],{},"これを Workers + Static Assets に移すと、",[48,951,952],{},"考え方が逆になる",[42,954,955,961],{},[45,956,957,958,960],{},"Pages：「全部 Functions、ただし ",[34,959,234],{}," で静的に逃がす」",[45,962,963,964,966],{},"Workers：「全部静的、ただし ",[34,965,118],{}," で SSR を挟む」",[10,968,969,970,973],{},"責任のデフォルトが反転するだけで、",[48,971,972],{},"最適化の発想は同じ","だ。だからこの構成も、いますぐ移す必要はない。ただし Durable Objects や Cron が欲しくなった瞬間に Workers 側でしか書けないので、機能要件が伸びれば移行が前提になる。",[80,975,977],{"id":976},"workers-の中にページ図が入ってるの腹落ち","「Workers の中にページ図が入ってる」の腹落ち",[10,979,980],{},"最初に持っていた素朴な疑問「ワーカーズの中にページ図が入っているのか？」は、半分正解で半分逆だった。",[42,982,983,989],{},[45,984,985,988],{},[48,986,987],{},"正解の半分","：いまの Workers には Pages 相当の Static Assets 配信が入っている。Pages でできていたことは Workers でほぼ全部できる",[45,990,991,994],{},[48,992,993],{},"逆の半分","：歴史的には Pages のほうが先で、Pages の中に Functions（＝ Worker）が住んでいた。それを Workers 側に移して、「Workers の中に Static Assets が住む」構造に組み直しているのが現在進行形のリファクタリング",[10,996,997,998,1001],{},"つまり「Pages も Workers も静的＋関数のセット」という構成自体は一貫していて、",[48,999,1000],{},"どっちのブランドの皮を被るか","だけが変わっている。新しい皮（Workers）に未来の機能が乗ってくるから、新規はそちら、というのが Cloudflare の言いたいこと。",[80,1003,1004],{"id":1004},"自分の運用への落とし込み",[10,1006,1007],{},"ここまで踏まえて、自分はこう動くつもりでいる。",[42,1009,1010,1019,1029],{},[45,1011,1012,1015,1016,1018],{},[48,1013,1014],{},"mdx-playground","：このまま ",[34,1017,573],{}," を続ける。完全 SSG なので Workers に移しても得るものがない。むしろビルドパイプラインを壊すリスクのほうが大きい",[45,1020,1021,1024,1025,1028],{},[48,1022,1023],{},"eurekapu-nuxt4","：当面 Pages のままだが、Cron や Durable Objects を使った機能（決算ビートの定期取得など）を新規に作るときは、",[48,1026,1027],{},"そのモジュールだけ別 Worker"," として切り出す。アプリ本体まで含めた全面移行は急がない",[45,1030,1031,1034,1035,1038,1039,1042],{},[48,1032,1033],{},"これから作る新規プロジェクト","：最初から Workers + Static Assets で組む。preset は Nuxt なら ",[34,1036,1037],{},"cloudflare-module"," 系、フレームワークなしなら ",[34,1040,1041],{},"wrangler init"," の Static Assets テンプレ",[10,1044,1045,1046,1049],{},"「Pages 推奨だったはずなのに気付いたら Workers 推奨になってた」と感じたのは、Cloudflare 自身がブランドを差し替えに行っている最中だからで、自分の感覚は間違っていなかった。ただ、慌てて全部移す必要もない。",[48,1047,1048],{},"動いているものはそのまま、新しいものは Workers で","、で十分間に合う。",[80,1051,1052],{"id":1052},"参考",[42,1054,1055,1062,1069,1075],{},[45,1056,1057],{},[22,1058,1061],{"href":1059,"target":25,"rel":1060},"https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/",[27,28],"Migrate from Pages to Workers · Cloudflare Workers docs",[45,1063,1064],{},[22,1065,1068],{"href":1066,"target":25,"rel":1067},"https://developers.cloudflare.com/workers/static-assets/",[27,28],"Static Assets · Cloudflare Workers docs",[45,1070,1071],{},[22,1072,1074],{"href":134,"target":25,"rel":1073},[27,28],"Cloudflare Pages vs Workers 2026: Updates, Pricing, Free Plan — cogley.jp",[45,1076,1077],{},[22,1078,1080],{"href":24,"target":25,"rel":1079},[27,28],"元ポスト（@catnose99, 2026-06-27）",[1082,1083,1084],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .svWSF, html code.shiki .svWSF{--shiki-default:#BDA437;--shiki-dark:#BDA437}",{"title":283,"searchDepth":296,"depth":296,"links":1086},[1087,1088,1089,1090,1094,1098,1099,1100],{"id":82,"depth":296,"text":83},{"id":143,"depth":296,"text":144},{"id":179,"depth":296,"text":179},{"id":224,"depth":296,"text":225,"children":1091},[1092,1093],{"id":349,"depth":302,"text":350},{"id":485,"depth":302,"text":486},{"id":526,"depth":296,"text":527,"children":1095},[1096,1097],{"id":536,"depth":302,"text":537},{"id":734,"depth":302,"text":735},{"id":976,"depth":296,"text":977},{"id":1004,"depth":296,"text":1004},{"id":1052,"depth":296,"text":1052},null,"「Pages 推奨」だったのに、いつのまにか「Workers の Static Assets が推奨」に変わっていた。Pages が廃止されるのか、Workers と何が違うのか、自分の2プロジェクトはどうなるのかを Before / After の図で整理した。","md",{},true,"/cloudflare-pages-to-workers-static-assets",false,"2026-06-29T00:00:00.000Z",{"title":5,"description":1102},"2026-06/2026-06-29/cloudflare-pages-to-workers-static-assets",[1112,1113,1114,1115,1116,1117,1118],"Cloudflare","Cloudflare Pages","Cloudflare Workers","Static Assets","Nuxt","SSG","デプロイ","wjQ3rGEaPga0u2HGpvOJNl0QC_LsiVJzdRwq5J7Nbgo",[],"https://log.eurekapu.com/og/blog/cloudflare-pages-to-workers-static-assets.png?v=2026-06-29T00%3A00%3A00.000Z&title=Cloudflare%20Pages%20%E3%81%AF%E3%82%82%E3%81%86%20Workers%20%E3%81%AE%E4%B8%AD%E3%81%AB%E4%BD%8F%E3%82%93%E3%81%A7%E3%81%84%E3%82%8B%20%E2%80%95%20Static%20Assets%20%E7%B5%B1%E5%90%88%E5%BE%8C%E3%81%AE%E5%9C%B0%E5%9B%B3&author=Kei%20Komatsu&sig=8754dd399bdcd483",1782885016722]