はじめに
HTML と CSS だけで作った小さなページを、サーバーを用意せずにインターネットへ公開したい場面があります。Cloudflare では、Workers の Static Assets を使うと、静的ファイルを Worker と一緒にデプロイして配信できます。
公式ドキュメントのコマンド自体は短いものの、初めて取り組むと「ファイルをどこに置くのか」「ローカル確認と公開の違いは何か」「公開 URL はどう決まるのか」で迷いやすくなります。筆者も 2026 年 9 月 26 日に Windows の PowerShell で作業した際、npm の起動エラーや workers.dev サブドメインの登録で足止めされました。本記事では、その実作業をもとに、初回公開までの流れとつまずいた箇所の対処を整理します。
- Workers Static Assets で静的サイトを作成し、
workers.devへ公開する手順 - PowerShell で
npm.ps1がブロックされた場合に、実行ポリシーを変更せずに進める方法 - 公開 URL のどの部分がプロジェクト名とアカウントのサブドメインに対応するか
- ローカルの
127.0.0.1:8787と公開 URL の違い、デプロイ出力の読み方
結論として、公開したい HTML・CSS はプロジェクト内の public フォルダーに置き、npm.cmd run dev でローカル確認、npm.cmd run deploy で公開します。公開 URL は「Worker 名.アカウントのサブドメイン.workers.dev」の形式になり、PowerShell で npm.ps1 がブロックされても、npm.cmd を指定すれば実行ポリシーを変更せずに作業を進められます。
Cloudflare Workers と Static Assets の概要
Cloudflare は、CDN、DNS、セキュリティ機能などを自社のグローバルネットワーク上で提供している事業者です。そのうち Cloudflare Workers は、同じネットワーク上でコードを実行するサーバーレスの実行環境です。本記事の手順を理解するうえでは、この 2 点を押さえておけば十分です。
Workers Static Assets の仕組み
Static Assets は、HTML、CSS、画像などのファイルを Worker の一部としてアップロードし、Cloudflare がキャッシュと配信を担う機能です。Wrangler の設定ファイルで指定した「アセットディレクトリ」の中身が、デプロイ時に自動でアップロードされます。
リクエストされた URL がアセットディレクトリ内のファイルと一致すれば、Worker のコードを実行せずにそのファイルが返されます。C3 の Static site テンプレートの設定を見ると Worker スクリプト(main)の指定がなく、静的ファイルの配信だけを行う構成です。この挙動は、後述する favicon.ico の 404 を理解する前提になります。
参考: Cloudflare Docs「Billing and Limitations」
“Requests to static assets are free and unlimited.”
(静的アセットへのリクエストは無料かつ無制限です。)
https://developers.cloudflare.com/workers/static-assets/billing-and-limitations/
同ページでは、アセットの保存に追加費用はかからず、Worker のスクリプトが呼び出されるリクエストは Workers の料金体系に従うと説明されています。ファイル数やファイルサイズの上限は「Platform Limits」のページで定められているため、大きなファイルを扱う場合は事前に確認することをおすすめします。
Cloudflare Pages との関係
静的サイトの公開には、以前から Cloudflare Pages も使われています。Pages は現在も提供されており、公式ドキュメントでは C3 CLI、Direct Upload、Git 連携の 3 つの作成方法が案内されています。一方で、同じページの冒頭では新規プロジェクトに Workers を使うよう案内されています。
参考: Cloudflare Pages Docs「Getting started」
“Workers supports most Pages use cases and offers a broader feature set”
(Workers は Pages のほとんどのユースケースに対応し、より幅広い機能を提供します。)
https://developers.cloudflare.com/pages/get-started/
既存の Pages プロジェクトを直ちに移行する必要があるという意味ではありません。これから新しく静的サイトを作る場合は、Workers Static Assets を第一候補に検討するのが現行の公式方針に沿った選択です。
検証環境と作業の全体像
筆者が作業した環境は次のとおりです。以降の手順とログの記述は、この環境での実作業に基づきます。
| 項目 | 内容 |
|---|---|
| 作業日 | 2026 年 9 月 26 日 |
| OS/シェル | Windows/PowerShell |
| Node.js | v24.21.0 |
| npm | 11.19.0 |
| create-cloudflare(C3) | v2.72.13 |
| Wrangler | 4.141.0 |
| プロジェクト名 | my-first-site |
作業の流れは「アカウント準備 → Node.js の準備 → プロジェクト作成 → public/index.html の編集 → ローカル確認 → デプロイ」です。応答時間の測定、独自ドメインの設定、GitHub 連携、アクセス制限、更新・停止操作は本記事の検証範囲外で、触れる場合は公式資料に基づく補足として記載します。
Cloudflare Workers で静的サイトを作成する手順
ここでは、Cloudflare アカウントと Node.js の準備から、C3(create-cloudflare)によるプロジェクト作成までを扱います。Cloudflare へのログインは初回デプロイ時にブラウザで行うため、この段階ではアカウントを作成しておけば問題ありません。
PowerShell で npm.ps1 がブロックされる場合
筆者の環境では、最初に npm --version を実行した時点で、PowerShell の実行ポリシーにより npm.ps1 を読み込めないというエラーが表示されました。PowerShell で npm と入力すると、PowerShell 用のスクリプトである npm.ps1 が呼び出され、実行ポリシーの制限を受けたためです。
このとき、実行ポリシーは変更せず、拡張子まで指定して npm.cmd を実行したところ、バージョンが表示されました。以降の作業もすべて npm.cmd で進めています。
参考: Microsoft Learn「実行ポリシーについて」
“実行ポリシーはセキュリティ境界ではなく、多層防御です。”
https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies
同ドキュメントによると、実行ポリシーはユーザーが意図せずスクリプトを実行することを防ぐ仕組みで、グループポリシーで設定された場合は PowerShell 側から変更できません。現在の設定は Get-ExecutionPolicy -List でスコープごとに確認できます。
組織が管理する端末では、実行ポリシーやソフトウェアの利用可否が所属先のルールで定められている場合があります。npm.cmd で進める方法を含め、作業は所属先のルールに従って行うことをおすすめします。
create-cloudflare でプロジェクトを作成する
作成コマンドは、Cloudflare Docs の「Static Assets: Get Started」に記載された npm create cloudflare@latest を、PowerShell 向けに npm.cmd へ置き換えたものです。
Cloudflare のサインアップページからアカウントを作成し、ダッシュボードへログインできる状態にしておきます。Workers の利用にドメインの登録は不要です。
C3 と Wrangler は npm 経由で実行するため、事前に Node.js のインストールが必要です。Cloudflare の「Install/Update Wrangler」では、Node.js の Current、Active、Maintenance の各リリースラインで Wrangler の実行をサポートすると説明されています。インストール後、PowerShell で次のコマンドを実行し、バージョンが表示されることを確認します。
node --version筆者の環境は Node.js v24.21.0 でした。インストール直後にコマンドが見つからない場合は、PowerShell を開き直してから再実行します。
PowerShell を起動した直後の場所が C:\WINDOWS\system32 になっている場合は、そのままプロジェクトを作成せず、ユーザーのフォルダーへ移動します。筆者は次のコマンドで、ログオン中のユーザーのプロファイルフォルダーへ移動しました。
cd $env:USERPROFILEnpm.cmd でバージョンが表示されれば準備完了です。
npm.cmd --version末尾の my-first-site がプロジェクト名です。現在のフォルダー(ユーザーのプロファイルフォルダー)の下に同名のフォルダーが作成され、後述する公開 URL の先頭部分にも使われます。
npm.cmd create cloudflare@latest -- my-first-site対話形式の質問が表示されるので、次項の選択内容を参考に回答します。
作成された my-first-site フォルダーへ移動します。以降のコマンドは、すべてこのフォルダーで実行します。
cd my-first-site筆者が C3 v2.72.13 で選択した内容は次のとおりです。
- 作成する内容
-
Hello World example を選択し、続くテンプレートの選択で Static site を選びました。Static site は Workers Static Assets を使う静的サイト用のテンプレートです。
- AGENTS.md の追加
-
Yes を選択しました。AI コーディングエージェント向けの説明ファイルで、今回の公開手順では使用していません。
- 初回デプロイ
-
No を選択しました。ページを編集してローカルで確認してから公開するためです。
公式ドキュメントには言語や Git 利用に関する質問も記載されていますが、表示される質問は C3 のバージョンによって異なる可能性があります。画面の指示を読み、上記以外の質問は用途に合わせて回答します。


public フォルダーと wrangler.jsonc の役割
公開したい HTML・CSS・画像を置く場所は、プロジェクト内の public フォルダーです。本記事の編集時に、create-cloudflare v2.72.13 の配布パッケージに含まれる Static site テンプレートを確認したところ、設定ファイル wrangler.jsonc ではアセットディレクトリが次のように指定されていました。
"assets": {
"directory": "./public"
}同じテンプレートでは、wrangler.jsonc の name に Worker 名が入る形になっており、デプロイ出力の Deployed my-first-site とも対応します。また、package.json の scripts には dev と deploy が定義されており、それぞれ公式手順の wrangler dev と wrangler deploy を呼び出します。本記事で npm.cmd run dev と npm.cmd run deploy を使うのはこのためです。なお、ここでの説明はテンプレートと公式資料に基づくもので、筆者が作成したプロジェクトの設定ファイルの内容を記録したものではありません。
public/index.html を編集してローカルで確認する
公開前に、自分の PC 上でページの表示を確認します。ここで確認できるのは自分の PC からの表示だけで、インターネットにはまだ公開されていません。
最小限の HTML に書き換える
筆者は public/index.html を日本語のシンプルな検証ページに書き換えました。次は同じ目的の最小構成の例です。日本語が文字化けしないよう、<meta charset="UTF-8"> を入れ、ファイルも UTF-8 で保存することをおすすめします。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Workers Static Assets 検証ページ</title>
<style>
body { font-family: sans-serif; max-width: 640px; margin: 40px auto; padding: 0 16px; }
h1 { color: #f38020; }
</style>
</head>
<body>
<h1>Workers Static Assets 検証ページ</h1>
<p>public/index.html を編集して表示を確認しています。</p>
</body>
</html>CSS を別ファイルに分ける場合も、public フォルダー内に置けば同じように配信されます。
npm run dev でローカルサーバーを起動する
プロジェクトフォルダーで次のコマンドを実行します。
npm.cmd run dev筆者の環境では Wrangler 4.141.0 が http://127.0.0.1:8787 で起動しました。ブラウザでこのアドレスを開くとページが表示され、ターミナルには GET / 200 OK が出力されました。トップページ(/)のリクエストが成功したことを示すログで、ローカル確認の成功を判断する根拠になります。


favicon.ico の 404 はページ本体とは別の問題
同じターミナルには GET /favicon.ico 404 Not Found も表示されました。ブラウザがタブのアイコンとして /favicon.ico を自動で要求したものの、public フォルダーにファビコンを置いていないため 404 が返った、という記録です。
参考: Cloudflare Docs「Static Assets」
“If no Worker script is present, a 404 Not Found response is returned.”
(Worker スクリプトが存在しない場合は、404 Not Found のレスポンスが返されます。)
https://developers.cloudflare.com/workers/static-assets/
前述のとおり Static site テンプレートには Worker スクリプトの指定がないため、アセットに一致しないパスは 404 になります。ページ本体の成否は GET / 200 OK で判断し、favicon.ico の 404 は切り分けて扱えます。気になる場合は、public フォルダーに favicon.ico を置くと解消が見込めます。
workers.dev へデプロイして静的サイトを公開する
ローカルで表示を確認できたら、Cloudflare へデプロイします。初回はブラウザでのログインと、アカウントの workers.dev サブドメインの登録が必要でした。
初回デプロイの流れ
プロジェクトフォルダーで次のコマンドを実行します。
npm.cmd run deploy未ログインの状態では、ブラウザが開いて Cloudflare の OAuth ログインを求められました。ブラウザでログインを完了すると、ターミナル側のデプロイ処理が続行しました。
アカウントに workers.dev サブドメインが未登録だったため、初回デプロイ時に登録を求められました。筆者は最初の候補名で Subdomain is unavailable と表示され、別の名前として mytech-lab を登録しました。すでに使われている名前は登録できないため、別の名前を指定します。
出力に表示された公開 URL をブラウザで開き、ローカルと同じページが表示されることを確認します。出力の読み方は後述します。
参考: Cloudflare Docs「General commands」
“Authorize Wrangler with your Cloudflare account using OAuth.”
(OAuth を使用して、Wrangler に Cloudflare アカウントへのアクセスを許可します。)
https://developers.cloudflare.com/workers/wrangler/commands/general/
同ページによると、ログインだけを先に済ませる wrangler login、ログイン中のアカウントを確認する wrangler whoami、認証を解除する wrangler logout も用意されています。筆者はデプロイ時のログインで作業を進めました。
公開 URL とプロジェクト名・サブドメインの対応
公開 URL は https://my-first-site.mytech-lab.workers.dev になりました。公式ドキュメントでは、Worker の URL は「Worker 名.サブドメイン.workers.dev」の形式と説明されています。
| URL の部分 | 今回の値 | 決まり方 |
|---|---|---|
| 1 番目のラベル | my-first-site | Worker 名。wrangler.jsonc の name で、Worker ごとに異なる |
| 2 番目のラベル | mytech-lab | アカウントの workers.dev サブドメイン。初回登録時に決め、アカウント内の Worker で共通 |
| 末尾 | workers.dev | Cloudflare が提供するドメイン |
mytech-lab はサイト個別の名前ではなく、アカウント側のサブドメインです。同じアカウントで 2 つ目の Worker を公開すると、1 番目のラベルだけが変わります。サブドメインは、ダッシュボードの「Workers & Pages」で「Your subdomain」の横にある「Change」から変更できますが、アカウント内のすべての Worker の URL に影響します。
Worker 名は URL の DNS ラベルとして使われるため、63 文字以内で、英数字とハイフンのみ、先頭と末尾にハイフンを使わないという制約があります。
ローカルの 127.0.0.1:8787 と workers.dev の違い
| 項目 | http://127.0.0.1:8787 | https://my-first-site.mytech-lab.workers.dev |
|---|---|---|
| 起動・公開のコマンド | npm.cmd run dev | npm.cmd run deploy |
| アクセスできる範囲 | 作業中の PC のみ | インターネット上の誰でも |
| Cloudflare へのログイン | 不要 | 初回デプロイ時に必要 |
| 停止した場合 | ターミナルを閉じるとアクセスできなくなる | PC を停止しても公開が続く |
| 用途 | 公開前の表示確認 | 実際の公開 |
127.0.0.1 は自分の PC 自身を指すアドレスのため、他の端末から同じアドレスを開いても検証ページは表示されません。公開状態は workers.dev の URL で確認します。
デプロイ出力の読み方と公開成功の根拠
筆者のデプロイ出力では、次の点を公開成功の根拠として確認しました。
public/index.htmlがアップロード対象として表示されている。Deployed my-first-siteと、デプロイした Worker 名が表示されている。- 表示された公開 URL をブラウザで開き、ページが表示される。
出力には Total Upload: 0.31 KiB という行もありました。これは Worker 側のバンドルサイズを示す値で、アップロードした index.html のファイルサイズではありません。HTML のサイズと比べて値が合わなくても、デプロイの失敗を意味するものではありません。


ページを更新する場合は、public フォルダー内のファイルを編集し、ローカルで確認してから同じ npm.cmd run deploy を実行します。筆者の検証は初回公開までで、再デプロイ時の出力は確認していません。
公開後に検討したい設定と GitHub Pages との使い分け
ここからは筆者が実施していない内容で、公式ドキュメントに基づく補足です。workers.dev の URL は、有効な状態では誰でもアクセスできます。業務で使う場合は、公開範囲と運用形態を事前に検討することをおすすめします。
参考: Cloudflare Docs「workers.dev」
“It’s recommended to run production Workers on a Workers route or custom domain”
(本番環境の Worker は、Workers ルートまたはカスタムドメインで運用することが推奨されます。)
https://developers.cloudflare.com/workers/configuration/routing/workers-dev/
同ページでは、workers.dev サブドメインは個人や趣味のプロジェクト向けと位置づけられています。閲覧者を限定したい場合は Cloudflare Access による認証、workers.dev の URL を無効化したい場合は wrangler.jsonc への "workers_dev": false の設定が案内されています。ダッシュボードで無効化しただけでは、次回の Wrangler でのデプロイ時に再度有効になる点に注意が必要です。
静的サイトを無料で公開する方法としては、GitHub Pages も選択肢になります。リポジトリを起点に公開したい場合は、GitHub Pages で自作ツールを無料公開する手順もあわせて参考になります。Cloudflare Workers は、ローカルからコマンドで公開でき、将来 Worker のコードや Cloudflare の他のサービスと組み合わせて拡張できる点が特徴です。
まとめ
Workers Static Assets を使うと、public フォルダーに置いた HTML・CSS をコマンド 2 つで確認・公開できます。初回はコマンドの実行方法やサブドメインの登録でつまずきやすいため、各段階で何を成功の根拠にするかを押さえておくと安心です。
- 公開したいファイルは public フォルダーに置きます。
- npm.ps1 がブロックされた場合は npm.cmd で進められます。
- ローカル確認は npm.cmd run dev、公開は npm.cmd run deploy を使います。
- 公開 URL は Worker 名とアカウントのサブドメインで決まります。
- favicon.ico の 404 はページ本体の表示とは切り分けて判断します。
- Total Upload は HTML ではなく Worker 側のバンドルサイズです。
- 新規の静的サイトは Workers を第一候補とするのが現行の公式方針
以上、最後までお読みいただきありがとうございました。

