筆者は ShipPress という Mac アプリの開発者です(Codotx, LLC)。記事の前半は自作ツールの操作手順ですが、後半のアップロード前チェックと各ホストへのデプロイ方法は、Simply Static などほかの方法で書き出した静的ファイルにもそのまま使えます。Netlify・Cloudflare・GitHub とは提携しておらず、アフィリエイトリンクもありません。
Claude Code にローカルの WordPress でカフェのサイトを作ってもらい、localhost では全ページきれいに表示されている。これを人に URL で見せたいだけなのに、レンタルサーバーを契約して、DB を書き出して、URL を置換して……となると腰が重くなります。
見せたいのがお知らせ・メニュー・アクセスのような普通のページだけなら、WordPress を動かし続ける必要はありません。全ページを HTML に書き出して、静的ホストに置けば済みます。この記事では、27 ページのサイトを静的コピーにして Netlify Drop で公開するまでと、同じフォルダーを Cloudflare Pages と GitHub Pages に置くときの注意をまとめます。
先に確認: 静的コピーで動かないもの
静的コピーは「その時点の HTML・CSS・画像」です。PHP が必要な機能は動きません。
| そのまま動く | 動かない(WordPress ホストが必要) |
|---|---|
| 固定ページ・投稿の表示 | WooCommerce のショップ・決済 |
| 画像、CSS、ページ間のリンク | 会員ログイン |
| 404 ページ、サイトマップ | コメント投稿 |
WordPress 宛てに送信するフォーム(admin-post.php など) |
右の列が必要なサイトは、静的化ではなく WordPress ごとホストに移します。ここでは左の列だけで足りるサイトを前提に進めます。
1. 静的コピーを書き出す(ShipPress の場合)
ShipPress は、自分の Claude Code / Codex / Cursor CLI などに Mac 上のローカル WordPress を作らせる無料アプリです。静的コピーはアプリから書き出せます。
- サイトを開き、右上の Go live をクリック
- Free address タブの一番下にある Only want the files? の Download the static copy and put it on another host yourself をクリック
- 全ページが書き出され、結果が検証されます。動画のサイト(Harbor Beans というコーヒー店)では
Done: 27 pages, 122 filesでした - Worth a look の一覧を確認。訪問者が開けない WordPress のダッシュボードへのリンクを含むページなどが挙がります
パーマリンクが /?p=123 のような基本設定のままだと、先に変更を求められます。Dashboard タブの Settings › Permalinks で Post name を選んで保存し、もう一度書き出してください。?p=123 は静的ホストから見るとすべて同じ index.html へのリクエストなので、ページごとのフォルダー(menu/index.html など)にしておく必要があります。
書き出し先は Show in Finder で開けます。Copy path でパスをクリップボードにコピーできます。中身はこういう構成です。
dist/
├── index.html # トップページ
├── 404.html
├── (サイトマップ)
├── menu/
│ └── index.html
├── contact/
│ └── index.html
└── ... # 画像・CSS など
(ファイル名の細部はサイトによって変わります)
2. アップロード前にローカルで確認する
ここからはどのツールで書き出したフォルダーでも同じです。まずローカルで、フォルダーをルートにして配信してみます。file:// で index.html を直接開くと、/menu/ のようなルート基準のリンクが壊れて見えるので、簡易サーバーを使います。
cd ~/path/to/dist # Copy path でコピーしたパス
python3 -m http.server 8000
# → http://localhost:8000/ を開いて、メニューやリンクを一通りクリック
次に、ローカル環境の名残と PHP 宛ての処理が残っていないかを grep します。
# ローカルの URL が残っていないか(JSON 内のエスケープされた形も拾う)
grep -rlE 'localhost|127\.0\.0\.1' .
# 静的ホストでは動かない WordPress 側の処理
grep -rlE 'wp-admin|admin-post\.php|admin-ajax\.php|wp-comments-post\.php' .
1 つ目でヒットしたら、書き出し前の WordPress 側でその URL を直してから書き出し直します。HTML を手で直しても、次に書き出したときに元に戻るからです。2 つ目でフォームが見つかった場合の対処は最後の章で触れます。
3. Netlify Drop に置く(アカウントなしで試せる)
- ブラウザーで https://app.netlify.com/drop を開く
- フォルダーをページにドラッグする(または folder をクリックしてフォルダーを選ぶ。選択画面にはコピーしたパスを貼り付けられます)
- Upload をクリック。ブラウザーがファイルのアップロード確認を出すので、もう一度 Upload
- 1 分ほどで your project is live と表示され、
○○.netlify.appのアドレスが発行される
Netlify にログインしていない状態でドロップしたサイトは、画面に出るパスワードで保護され、1 時間だけ公開されます。残したい場合は Claim this site から無料アカウントに紐付けます(Netlify の条件は変わることがあるので、登録時に画面の説明を確認してください)。
公開後に、いくつかのページが 200 で返ってくるかを確認しておきます。
for p in / /menu/ /contact/ /this-page-does-not-exist/; do
printf '%s ' "$p"; curl -s -o /dev/null -w '%{http_code}\n' "https://○○.netlify.app$p"
done
最後の行は 404 が返り、404.html の中身が表示されれば正常です。パスワード保護中はパスワード画面が返るので、Claim した後に確認します。
更新するとき
静的ホストは WordPress の変更を自動では拾いません。表示されるのは最後にアップロードしたファイルです。サイトを直したら、静的コピーを書き出し直し、Netlify の同じサイトの Deploys 画面に新しいフォルダーをドロップします。
CLI で済ませたい場合は Netlify CLI も使えます。
npx netlify-cli login
npx netlify-cli deploy --dir=. --prod # 初回はどのサイトに紐付けるか聞かれる
4. Cloudflare Pages に置く
ダッシュボードから Pages プロジェクトを作ってフォルダーをアップロードするか、Wrangler で直接デプロイします。
npx wrangler login
npx wrangler pages deploy . --project-name=harbor-beans
harbor-beans.pages.dev のようなアドレスで公開されます。更新時は書き出し直して同じコマンドを流すだけです。
5. GitHub Pages に置く(サブパスに注意)
リポジトリにフォルダーの中身をルートに置いて push し、リポジトリの Settings › Pages で公開元のブランチとフォルダー(/ (root))を選びます。
cd ~/path/to/dist
git init && git add . && git commit -m "static copy"
git branch -M main
git remote add origin git@github.com:<user>/<repo>.git
git push -u origin main
ここで 1 つハマりどころがあります。ShipPress の静的コピーのリンクはルート基準(/menu/)です。普通のリポジトリを Pages にすると https://<user>.github.io/<repo>/ というサブパスで公開されるため、/menu/ が https://<user>.github.io/menu/ を指してしまい、トップ以外が 404 になります。
回避策はどちらかです。
-
<user>.github.ioという名前のリポジトリにする(ルートで公開される) - 独自ドメインを設定する(Settings › Pages › Custom domain)
Netlify と Cloudflare Pages はプロジェクトごとにルートで公開されるので、この問題は起きません。手軽さで選ぶなら Netlify か Cloudflare Pages の方が素直です。
6. フォームが見つかったら
手順 2 の grep で admin-post.php などが出た場合、静的ホストではそのフォームは送信できません。選択肢は次のとおりです。
- 外部のフォームサービスや予約サービスの埋め込みに置き換える
-
mailto:リンクにする - 送信機能が必要なら、静的化をやめて WordPress ごとホストに移す
ShipPress の場合、設定なしでフォームの送信内容をメールで受け取りたいなら、静的コピーではなく Go live の無料の ShipPress アドレスで公開する方法もあります。ショップや会員機能があるサイトは WordPress host タブからホストに移します。
動画
Harbor Beans を静的コピーにして Netlify Drop で公開し、Claim するところまでを録画しています(3 分 54 秒)。
- 文章版の手順(日本語): https://shippress.codotx.com/ja/docs-static-netlify?ref=qiita
- ShipPress(無料・Mac): https://shippress.codotx.com/?ref=qiita
- 前回の記事(1 つのサイトで AI エージェントを並列に動かすときの分け方): https://qiita.com/shippress/items/49c78e04349190045e2c
まとめ
- フォーム・ショップ・ログインがなければ、静的コピーで十分
- 書き出す前にパーマリンクを Post name に。書き出した後は
python3 -m http.serverと grep で確認 - 試すだけなら Netlify Drop、継続して更新するなら Netlify CLI か
wrangler pages deploy - GitHub Pages はサブパス公開でルート基準のリンクが壊れるので、
<user>.github.ioリポジトリか独自ドメインで
静的化したサイトで、問い合わせフォームをどう置き換えていますか。外部フォームサービス、mailto:、それとも静的化をあきらめて WordPress ごと移すか。決め手があればコメントで教えてください。