タイトルの通りだが、このブログをAstroベースでリニューアルして、プラットフォームを以前使っていたCloudflare PagesからCloudflare Workersに移行した。ちなみに内部の実装は移行を含めてほぼ100% Claude Codeがやっており、私自身は本気で全くコード書いてない。その辺の話もしていきます。
そもそもなんで移行したのか
Cloudflare公式がCloudflare PagesからCloudflare Workersへの移行を促しはじめたのがそもそもの始まりである。現行ブログはCloudflare Pagesで動いていたので、前回の移行(はてなブログ⇒Hugo+Cloudflare Pages; はてなブログに飽きた)とは意味合いが違っており、移行を余儀なくされてしまったということである。ちなみにてっきり「Cloudflare Pagesは近いうちになくなる」と思ってたが、この辺の記事読む限りだと少し違うらしい。まあ結局移行するんだったら当事者にとっては同じなんだが…
CloudflareがAstroを買収したのも、重い腰をあげた一つのきっかけになっている。だらだら悩んでいるところにちょうどいいフレームワークがCloudflare公認として入ってきちゃったなー、良い機会だしやるかー、という感じ。なのでこの時点で、時期はともかく次はAstroに移行しようとは考えていた。最初はCloudflareのAstroガイドを読みながらプロジェクトの初期化だけして、記事の形式がHugoと比較的似てるなーと思いつつ、本格的には着手しておらず、そのまま1~2か月経過したころ(2026年5月下旬)に、気まぐれでClaude CodeのProプランを契約したので、じゃーClaudeと一緒にやってみるかと始めた。
移行振り返り
上で書いてる通りで、サイトデザイン、タグやカテゴリ・年月別の集計処理、ページャーの実装、見出しのアンカーリンク、フロントマターの追加、キーワード検索の導入、Adsenseの導入、その他諸々細かい実装や修正…とそれらに伴うビルド処理の実装・修正、およびビルドの検証、加えて既存のHugo形式の記事の移行(記事形式変換スクリプトの作成や実行)などなど、諸々ほぼ100% Claude Codeにまかせっきりで、私はターミナルに「あーしろ」「こーしろ」と指示していただけである。なので実際、細部の動作や仕様はまったくわかってない。わかる必要もないというか、わからなければClaude Codeに聞けばいいと思ってるので、それが大きな問題になり得るとも思ってない。これは正直良い面も悪い面もあるとは思ってるが、この話の本筋ではないので別の記事で改めて綴ろうと思う。とりあえず、今回の移行に際して主要なポイントとなった部分を整理してみる。
- プロジェクトはAstroのブログテーマをベースに開始したもので、そこからデザインは基本的には大きく変えていない。現行は右サイドバーにタグやアーカイブのリンクを付けているけど、今更特に強いこだわりがあるわけでもないし、デフォルトのレイアウトからわざわざ大きく変えることもあるまいと思い、タグやアーカイブのリンクはトップページに移動となった。また、デフォルトだとPC版ではトップページに左右に2記事が並ぶようなレイアウトになってたが、なんとなく見栄えが変だったので1行1記事に直した。
- Astroのデフォルトには「タグ」や「カテゴリ」といったフロントマターの項目(Taxnomy)は存在しないので、追加した。ついでにビルド時に対象記事を集めて一覧にする処理も実装。パスは現行と同じにした。年月別も基本的には同様だが、Hugoのときは記事そのものの日付とは別に
archiveという専用のTaxonomyを用意した一方、今回はAstroの記事の日付pubDateをそのまま採用したので記事のフロントマターの管理がわかりやすくなった。この辺、Hugoのときは全部自分で頑張って手で実装したんだが(こことかここでその記録が垣間見れる)、Claude Codeを知ってしまった今となっては最早考えられないな……苦行としか思えない……(もうやりたくない) - ページャーは現行同様前後1ページにだけ移動できればよかったんだが「ページャー実装して」とだけお願いしたら全ページへの直接リンクまで作ってくれたので、じゃあもうこれでいいやと思いそのままにしている。視認性が大きく損なわれるようなことがあれば修正するかもしれない。各記事の一番下にある「前の記事」「次の記事」もついてなかったのでページャーのついでに付けた。
- 現行で実施していた見出しへのアンカーリンクの実装も、Claude Codeに頼んだだけで簡単に実装してくれた。Hugo時代は結構苦労したのになあ、これ…Claude Codeだと数秒か……
- AstroにはHugoにはある「下書き(
draft)」のフロントマターが(デフォルトでは)どうも存在しないようである。このGithub Issueでそんな内容が取り上げられており、結局実装しないままで終わってるらしい。なのでClaude Codeに作ってもらった。新規作成時は固定でtrueにして、本番にpushする前に手動でコメントアウトする運用。シンプル。 - キーワード検索は引き続きPagefindを使っている。Hugoのときは、Pagefindの最新版を
wgetでとってきてHTML生成後に実行するという自前の個別スクリプトを実行していたのだが、Astroには専用のPagefindがいるらしくて(astro-pagefindというやつ、個人のOSSだが)、それ使いますねとClaude Codeに言われたのではいどーぞとお願いして作ってもらった。トップページに埋め込まれていた検索ボックスが別ページに独立したが、これはClaude Codeのデフォルトの案である。個別にカスタマイズもできますがどうしますか?と言われたがじゃあそのうちやるかも…といってGihub Issue作成させた。こういうのはたいてい塩漬けで後になってもやることはないんだが万が一気まぐれで修正したくなったときに情報として残しておくと役に立つものだ。知らんけど。 - レイアウトが少し変わったので、それに見合う形でAdsenseの広告ユニットを新設して設置。ちなみに「レイアウト的に広告ユニット新設したほうがいいよ」というのもClaude Codeからのアドバイスである。
- 内部運用の話だが、
hugo newコマンドに相当するもの(記事を新規作成するときにarchetypeをもとに記事ひな形のmdファイルを作成するコマンド)がAstroに用意されてないらしかったので、そのためのスクリプトも作ってもらった。単純なshellだが地味に役立つ。この記事もそのスクリプトから開始した。 - 細かい話だが、「上へ戻る」アンカーを実装した。現行のHugoブログだとあまり気にならなかったんだが、Astroだと文字がでかいせいかページが縦長でスクロールが長く続く傾向があり(ように思えた)、あったほうが便利だなと思ったので。こういうちょっとした開発、Claude Codeですぐにできるのは素晴らしい。
- 前回の、はてなブログ->Hugoと異なり、画像の移行は不要で、全部の記事が既にMarkdownファイルとして存在していたうえ、項目は違えど「フロントマター」という共通の仕様があるため右から左に単純移行がしやすく、かつ今回は面倒な実装をClaude Codeが全部吸収してくれたので、前回に比べて移行は断然楽だった。というか多分合計して5分かかっていないと思う。最初は「ツール作って」とだけ指示したのだが、というのも作ってさえもらえれば実行は自分で出来るし、Claude Codeにやらせてトークン消費させるのも勿体ないし、と思っていたら、作るにとどまらず実行までやってくれて、意図せず1~2回の指示ですべての移行が完了した。
- 500以上の記事のHTML生成、タグ・アーカイブ・ページャーなどのパスの生成、Pagefindの索引生成を含めても、Cloudflare Workersのビルドは合計で1.5分程度。個人的にはこれでも十分高速なのだが、直近最後に実施したHugoブログのビルドは同規模を44秒で完了しているので、やはりHugoのほうが速い。さすが世界最速を謳っているだけある。ただAstroのビルドも十分高速で、実際、Cloudflare Workersのビルドタイムアウトは20分らしいし、全く支障はない。
- Cloudflare Workers向けのAstroパッケージは、デフォルトでWorkers KVを用意する、らしい。このため何も考えずにCloudflare Workersにデプロイすると、知らない間にWorkers KVが出来上がっている。で、2回目以降も同じようにKVを作成しようとするので、デプロイが落ちる。ここで議論されている。「このGithub Issue見て直して」とClaude Codeにお願いしたところ、このKVはセッション管理用に用意されるものらしく、SSGのブログでは不要ということのようで、
astro.config.mjsの修正とKV削除して対応した。そうですか。 - その他、レイアウトの変更に伴い、色々乱雑に貼ってあったリンクなどを取っ払ったりした。見た目は結構すっきりしたんじゃないかと思う。
- 比較的大きめの修正(Pagefindの検索実装とか)を行うと一気にトークンが15~20%程度まで膨らんだことはあったが、最大でも60~70%までいった程度で、開発中リミットに悩まされることはなかった。ただ、ターミナル立ち上げたまま数時間~一晩放置してまた作業開始、ひと段落ついたらまた放置~…みたいなことを繰り返してダラダラ作業しており、途中で何度もリセットがかかっていたので、たまたま回避できていただけという可能性はあると思う。集中的に開発していたら恐らくどこかでリミット達していたのだろう。潜在的な指示の悪さ(非効率なトークンの消費)がある自覚はあるが、この程度のブログの開発でもトークンリミットの危険性があるというのは学びになった。Proプランだとどんな開発してたとしても調子のってるとすぐにリミット到達してしまいそうである。まあ個人でProプラン使ってる範囲ならこんなものかなという感じで、時間調整しながらちょっとずつやっていくので調整もできそうなので、今の所はそこまで大きな不満でもない。
今後のこと
以下は現時点で対応していないが、そもそもどう対応していこうか自分の中で決まってない内容。
目次の実装
Hugoは記事内のh2やh3タグなどを読み込んでビルドの時に記事の上部に自動で目次作ってくれる(ようなテーマをそのまま採用した)。が、Astroにはそれはなく、いや作ろうと思えば作れる(Claude Codeが作るんだけど…)んだろうけど、問題なのは
- (1) はてなブログ時代 (目次に該当するコンテンツが既にMarkdownに書かれている; MTファイルエクスポート時点で出力されていたため)
- (2) Hugo時代 (Hugoのビルドでつくってもらう前提だったのでMarkdownファイルには目次を付けていない)
でMarkdownファイル内に既に「目次」に相当するものがいるかどうかが分かれており、一概に「h2とかh3見て目次作って」と指示できないのである。これもあって現時点では「目次自動作成」は作ってない。筋から言うと、(1)から現存する「目次」を全部取っ払って、各記事には独自の「目次」を持たないようにしつつ、ビルド時に自動で目次つくってもらうのが一番きれいなんだろうけど、(1)の記事数が多いのと、統一されたフォーマットで書かれているわけでもないのでClaude Codeもきれいに取り払えないのではないか、という懸念があり(見逃すくらいならまだよくて、余計な部分を消してしまうことの方が怖い)、若干及び腰である。Claude Code頭いいからやってくれそうな気もしないでもないけどな…
逆に(2)Hugo時代 の記事は記事数がそこまで多くないので、こいつらに手動でちょいちょい付けていき、今後も基本的に、「必要なら目次は自分で作る」をルールにしたほうがわかりやすいのではないかという気になっている。こっちのほうが現実的な気もするので、その方向でいくかもしれない。
昔の記事の見直し
今まで積極的にやってこなかったが、今回改めてみると、はてなブログ時代の記事は、コードスニペットなどが汚くて見づらいし、中にはそもそもHTMLの構文が壊れているのすらある。はてなブログからエクスポートしたMTファイルを分解してMarkdownとして切り出したものだが、当時いろいろゴチャゴチャとやってたので、そのミスというか考慮漏れみたいのが残っているのだろう。この時に今のClaude Codeもってやり直したい。
ただ、アクセス状況見ると、ほとんどの過去記事はアクセス自体されていないので、多分誰も気づいていない(俺以外)。そんな過去の遺産にClaude Codeのトークン消費するのも勿体ないので、どうしようか悩み中。しらみつぶしに昔の記事の順に対処、はちょっとイケてないので、例えば1週間ごとにアクセス状況を見て、よくアクセスされる記事から順に適宜直していく、でもいいかもなと、今はそんなことを考えており、CloudflareのWeb AnalyticsのデータにアクセスできるAPIないかなと探していたりする。ここにそれっぽいAPIが載ってるんだが、「サイトの情報」だけで「アクセス数」が取れるわけではないっぽい。ダッシュボード覗かないとだめかな?…とまあ、そんな感じ。
おわりに
Claude Codeのおかげですごくスムーズに移行が出来た。今回はもとがHugoでAstroと比較的近いものだったので、特にコンテンツ系の移行にほとんど苦労することがなかったのも大きいが、Claude Codeに任せれば、はてなブログなど全然違うプラットフォームが移行元でもそれほど苦せず移行できそうな気はする。(トークンの消費は激しそうではあるので、期間はかかりそう)この作業体験には今更ながら凄く感動しており、今まで使ってこなかったことを後悔しているレベルだが、一方で完全にClaude Code任せにしていて中身をあまりわかってないことには少なからず危機感も感じており、この辺のモヤモヤはそのうち別途記事にまとめたい。
とりあえず移行は済んだが上にあげている残課題系の対応などを含め、微調整はしていくつもりである。それでは。