Next.js静的サイトをCloudflare Pagesへ出す:build・sitemap・独自ドメインを別々に検証する
kikuta.devの実構成を使い、Next.js static exportからCloudflare Pages deploy、custom domainのproduction確認までを分離する。
Next.jsの静的サイトをCloudflare Pagesへ出しているが、build成功だけで独自domain・sitemap・metadataまで正しいと思い込んでいるとき。
static export、content-driven sitemap、metadataBase、Cloudflare deploy、production URL検証を別gateとして確認する方法。
本番成果物をoutディレクトリへ固定する
kikuta.devではNext.jsのnext.config.jsにoutput: “export”を設定しています。production buildの結果は静的なoutディレクトリへ落ちるため、Cloudflare側でNode.js application serverを動かすことを本番要件にしていません。
ローカルではpnpm lint、pnpm exec tsc –noEmit、pnpm exec next build –webpack、git diff –checkを通してから配布します。buildが通るか、型が通るか、不要なwhitespace差分がないかを一つの結果へまとめず、別のfailureとして確認しています。
URL一覧を手で二重管理しない
記事とProjectはsrc/lib/content.tsの配列を正本にし、sitemap.tsはその配列から/articles/
root layoutではmetadataBaseをhttps://kikuta.devへ固定し、各記事・Project側はrelative canonicalを返します。Open Graphやcanonicalの基準URLをpageごとに文字列連結しないことで、metadataの生成規則も一箇所へ寄せています。
Pagesへのdeploy成功とcustom domainの公開成功は別
配布はnpx wrangler pages deploy out –project-name kikutaで行います。Wranglerが返すpages.devのdeployment URLはupload結果を確認するには便利ですが、利用者とcrawlerが見るkikuta.devで同じHTMLが返ることまでは証明しません。
そのためdeploy後はkikuta.devの実URLへcurl -fsSLを送り、今回追加した見出し・Project link・article linkなど具体的な文字列を検査します。『Cloudflareのdeploy commandが0で終了した』ではなく、『public URLから期待したartifactを読める』を最後のacceptanceにしています。
robotsとsitemapもbuild対象として扱う
robots.tsとsitemap.tsもNext.jsのstatic routeとして生成します。robotsは全pathをallowし、sitemapとhostをkikuta.devへ向けます。記事本文だけ更新して終わりではなく、公開surfaceに含まれるmachine-readableな入口も同じbuildから出力します。
この構成の利点はCloudflare Pages固有の設定を増やさないことです。content、metadata、sitemap、robotsをNext.js側のsourceへ置き、Cloudflare Pagesは生成済みの静的成果物を配る役割へ絞っています。