副業ブログ運営記録
Cloudflare Pages noindex問題|_headers1行で抜けた実体験
副業ブログ運営記録

Cloudflare Pages noindex問題|_headers1行で抜けた実体験

#Cloudflare Pages #SEO #インデックス問題 #副業ブログ #非エンジニア

こんなことで困っていませんか

  • Cloudflare Pages にブログをデプロイしたのに、Google にいつまで経ってもインデックスされない
  • Search Console で「サイトマップを取得できませんでした」エラーが出続ける
  • 検出されたURL数が「0件」のまま動かない
  • 独自ドメインを取らずに *.pages.dev のままで運用していると、検索流入は本当に得られないのか不安

自分も Day1〜Day29 までの1ヶ月、まったく同じ状況で詰まっていました。 記事を19本書いても Google に見つけてもらえない。原因がサイトマップ XML の不備なのか、共有サブドメインの権威性が低いせいなのか、それとも独自ドメインを取らないと一生インデックスされないのか、本気でわからなくなっていました。

結論から先に書きます。

  1. 真因は、2026-05時点で *.pages.dev ドメインに自動付与される Cloudflare Pages 既定の X-Robots-Tag: noindex でした
  2. blog/public/_headers ファイルに1行追加するだけで解決しました
  3. サイトマップ取得不可エラーは副次的症状で、サイトマップ自体に問題はありませんでした

この記事では、同じ罠にハマっている非エンジニア副業ブロガーに向けて、真因に辿り着くまでの調査経緯と、_headers 1行で抜け出した実体験を書きます。

用語のかんたん説明(先に把握しておくと読みやすいです)

  • noindex:検索エンジンに「このページを検索結果に出さないでください」と伝える指示のこと
  • X-Robots-Tag:HTTP レスポンスヘッダーに書かれる検索エンジン向け指示。HTML の meta タグ版と効果は同じだが、XML や PDF にも効かせられる
  • curl:コマンドラインから URL を叩いてレスポンスを確認するツール。curl -I でヘッダーだけ見られる
  • _headers ファイル:Cloudflare Pages 専用の設定ファイル。blog/public/_headers に置くと、デプロイ後に HTTP レスポンスヘッダーをカスタマイズできる
  • プレビュー環境:本番公開前に確認する用の URL。Cloudflare Pages では PR ごとに自動生成される
  • カスタムドメイン:example.com のような独自ドメイン。*.pages.dev の代わりに使える
  • サイトマップ XML:サイト内のページ一覧を機械可読な形式でまとめたファイル。Search Console に送信して Google にクロール対象を伝える

Cloudflare Pages noindex問題で詰まっていた1ヶ月

このブログは Day1(2026-04-04)に Cloudflare Pages で公開してから、Day29 までの約1ヶ月間、Google の検索結果にほとんど登録されていませんでした。

恥ずかしい話ですが、最初の数週間は Search Console や GA4 をほとんど開いていませんでした。「副業ブログを始めたばかりだし、そんなにアクセスはないだろう」と決めつけていて、数字を見る習慣を作れていなかったんです。確認して「0」と突きつけられるのも、無意識に避けていたところがあります。

転機は、Day28 あたりにようやく Search Console を開いた瞬間でした。画面に表示されていたのは、こういう数字です。

  • 公開記事数: 19件
  • インデックス登録済み: 3件
  • サイトマップ送信状態: 取得できませんでした
  • 検出されたURL数: 0件

19記事中3件しか検索結果に登録されていない。しかもサイトマップは何度送り直しても「取得できませんでした」のまま。何かがおかしい、ということだけは分かりました。

このときの困惑と、当初立てた2つの仮説(サイトマップ XML の不備・共有サブドメインの権威性劣位)は、Day29 に pages.devで19記事書いてもインデックス3件だった話 として正直に公開しました。

ところが、記事21を書いている時点でもまだ真因は分かっていませんでした。サイトマップを送り直しても結果は変わらず、「変数を1つずつ消す」ために独自ドメイン取得(年1,400円程度)まで準備していたほどです。

その購入を実行する直前に、開発部の dev-engineer エージェントへ「もう少し技術的な深掘りをしてほしい」と依頼することにしました。これが、真因発見の入り口でした。

1ヶ月インデックスされなかった頃の正直な気持ち

書いても書いても誰にも届いていない感覚で、絶望とまでは言いませんが、残念な気分でした。SNSの反応だけが唯一の手応えだったので、そこからも反応がない日は静かに凹みました。

もともと「副業ブログを始めたばかりだし、そんなにアクセスはないだろう」と思っていたので、覚悟はしていたつもりです。それでも、Search Console の「検出URL 0件」という数字は、やはり見たくなかった、というのが正直なところです。見ないようにしていた、と言ってもいいかもしれません。

公開すれば全部完了している、と思い込んでいたのも情けない話です。事前にもう少しちゃんと調べておくべきだったと、今は反省しています。

当初疑った2つの仮説(サイトマップ・共有サブドメイン)が外れた経緯

記事21の時点で立てていた仮説は2つでした。

仮説1:サイトマップ XML の構造不備

@astrojs/sitemap で生成された sitemap-index.xml<lastmod> <changefreq> <priority> が含まれていない状態でした。Google はこれらの情報がないとクロール優先度を判定しにくいので、ここを補強すれば解決するかもしれない、と考えていました。

仮説2:共有サブドメイン(*.pages.dev)の権威性劣位

shikumi-no-tane-v6.pages.dev は Cloudflare Pages の共有ドメイン配下なので、独自ドメインに比べて検索エンジンからの評価が低い可能性がある、という仮説です。これが真因なら、独自ドメイン取得(年1,400円程度)以外に解決策がないことになります。

5/2〜5/3 にかけて、開発部の dev-engineer エージェントが追加調査に入ってくれました。AIカンパニー化(13部署体制)の経緯は Claude Code でAIカンパニーを作った話 に書いてあります。1人会社では絶対に手が回らない深掘り調査を、専門家エージェントに第三者目線で任せられるのが今の体制の強みです。

dev-engineer がまず実行したのは、本番URLへの単純な curl -I でした。

curl -I https://shikumi-no-tane-v6.pages.dev/

返ってきたレスポンスヘッダーに、見覚えのない1行が含まれていました。

HTTP/2 200
content-type: text/html
x-robots-tag: noindex
cf-ray: ...

cf-ray は Cloudflare がリクエストごとに発行する識別子で、値は毎回変わるため本記事では ... で省略しています)

x-robots-tag: noindex

これが返ってきている時点で、サイトマップ XML を完璧に整えても、独自ドメインを取らなくても、Google は「このサイトは検索結果に出さないでください」という指示を毎リクエストごとに受け取り続けていたことになります。

仮説1(サイトマップ構造)は的外れではないが副次的、仮説2(共有サブドメイン劣位)も大筋は外れ。真因は別にありました。

調査結果を見たときの率直な感想

自分1人だったら、まずたどり着けなかったと思います。AIカンパニー化を進めて専門家エージェントを採用しておいて、本当に良かったというのが一番強い感想です。

同時に、AI も間違えることがあるんだな、と気づかされました。記事21の段階では「サイトマップ未送信」「共有サブドメインの権威性劣位」という仮説を AI 自身が提示してくれて、自分もそれを信じていました。仮説を持つことと、それが真因と一致することは別物なんだ、ということを実感した瞬間でもあります。

ここまで来てしまえば、_headers の修正だけで解決するなら独自ドメインは必須ではない、とも思いました。それでも、自分とは別の視点で物事を切ってくれる専門家ロールがあることの価値は大きかったです。素人運営でも、エージェントを活用することで踏み込める領域があるんだ、というのが今回の調査結果から得られた一番の収穫でした。

真因はCloudflare Pages公式仕様だった(pages.dev デフォルトnoindex)

調査を進めると、Cloudflare Pages の公式ドキュメントに次のような記述がありました。

Cloudflare adds a X-Robots-Tag: noindex header to responses served from *.pages.dev subdomains by default to prevent preview deployments from being indexed by search engines.

(出所:Cloudflare Pages 公式ドキュメント・Custom Domains セクション。https://developers.cloudflare.com/pages/configuration/custom-domains/ / 関連: https://developers.cloudflare.com/pages/platform/headers/。2026-05時点で確認)

意訳すると、

「Cloudflare は *.pages.dev サブドメインから返すレスポンスにデフォルトで X-Robots-Tag: noindex ヘッダーを付与します。プレビュー環境が誤って検索エンジンにインデックスされないようにするためです」

この仕様自体は Cloudflare 側の親切設計です。Pull Request ごとに自動生成されるプレビュー URL(例:abc123.shikumi-no-tane-v6.pages.dev)が検索結果に紛れ込むと、ユーザーは古い情報や未公開のページに飛んでしまう。それを防ぐためにデフォルトで noindex を付けてくれている。

ただ、独自ドメインを取らずに *.pages.dev を本番運用している副業ブロガーにとっては、これは罠になります。

図書館に例えるとこうです。

「司書(Googlebot)が本(記事)を取りに行ったら、貸し出しカウンターで本と一緒に『この本は棚に並べないでください』というメモを毎回手渡されていた。司書はその指示を尊重して、本をそのまま倉庫に戻した」

棚に並ばない(=検索結果に出ない)のは、本(記事)の中身が悪いからではなく、本に毎回付いてくる指示メモのせい。本を書き直しても、サイトマップを整えても、メモの内容を上書きしない限り、永遠に棚に並びません。

親切設計が罠になったことについて

結論として、Cloudflare 公式の仕様なので誰も悪くないと思っています。むしろ、自分のように本番運用してしまう人を含めて全体の事故を減らすための丁寧な親切設計だ、とも感じました。

悪いのは、そもそも公式ドキュメントの「デフォルト設定」を最初に読んでいなかった自分の方です。デフォルトで noindex が付くという仕様は、書かれている場所を読みに行けばちゃんと書いてある情報でした。

ただ、親切設計と「自分が気づけない」は紙一重だな、ということも同時に感じました。善意で守られているはずの仕組みが、想定外の使い方をする人にとっては罠になる。設計と運用のすれ違いって、こういうところに静かに潜んでいるんだなと思いました。

_headers ファイル1行で解決した拍子抜けの瞬間

解決策は拍子抜けするほどシンプルでした。

blog/public/_headers ファイルを新規作成し、サイト全体に明示的に X-Robots-Tag: index, follow を返す設定を1行入れる。

/*
  X-Robots-Tag: index, follow

/sitemap-index.xml
  X-Robots-Tag: noindex, follow

/sitemap-0.xml
  X-Robots-Tag: noindex, follow

設定の意味はこうです。

  • /*(全ページ)に index, follow を返す → Cloudflare 既定の noindex を上書き
  • サイトマップ XML 自体は noindex, follow(検索結果には出さないが、サイトマップ内のリンクは辿らせる)→ SEO 標準の作法

ビルドすると、dist/_headers に同じ内容が出力され、デプロイ時にCloudflare 側で読み込まれます。

[@astrojs/sitemap] `sitemap-index.xml` created at `dist`
28 page(s) built in 3.35s

dist/_headers dist/_redirects がデプロイ成果物に含まれることをローカルで確認してから、main にマージしました。

mainマージ後、Cloudflare Pages の自動デプロイ完了(約2〜3分)を待って、再度 curl -I で確認します。

curl -I https://shikumi-no-tane-v6.pages.dev/

実際に返ってきた出力(修正後):

HTTP/2 200
content-type: text/html
x-robots-tag: index, follow
cf-ray: ...

x-robots-tagindex, follow に上書きされていれば成功。Googlebot が次回クロール時に「このページは検索結果に出して良い」と判断してくれるようになります。

その後の作業は Search Console 側の操作だけです。

  1. Search Console → 左メニュー「サイトマップ」
  2. 既存の sitemap-index.xml を選択 → 「サイトマップを削除」
  3. 「新しいサイトマップの追加」に sitemap-index.xml を入力 → 送信
  4. ステータスが「成功しました」になればOK
  5. 2〜3日後に「検出されたURL数」が24以上になっているか確認

1ヶ月悩んだ問題が、_headers ファイル3行(実質1行)で抜けました。

1行で解決すると分かった瞬間の本音

デフォルトの noindex 設定を _headers で上書きするだけで解決してしまうと知ったときは、正直、拍子抜けしました。1ヶ月インデックスされなかった原因が、たった1ファイルの追加で解消する、というスケール感のギャップに、なんとも言えない気持ちになりました。

「もっと早く自分で公式ドキュメントをちゃんと読んでおけば、こんなに長引かなかったのに」という反省はあります。一方で、初心者ほどこの設定には気づきにくい、というのも事実です。

だからこそ、これから Cloudflare Pages でブログを始める非エンジニアの方が同じ罠にハマらないように、自分が学んだことをそのまま記事に残しておきたい、と思うようになりました。困ったときに気づきにくいポイントを、ちゃんと言葉にしておく。同じところで詰まる人が一人でも減れば、書いた意味があったと思っています。

結局 独自ドメイン shikuminotane.com を取得した理由(SEO運用前提への方針転換)

_headers で対処できた直後、独自ドメイン取得はいったん「保留」に戻しました。_headers 1行で根治できる目処が立った以上、年1,400円の固定費を増やす必要はない、というのが当時の判断です。「無料で粘る」という当初の検証テーマも、まだ終わらせたくありませんでした。

ところが、保留を確定させる前にもう一度 Cloudflare Pages の公式ドキュメントを読み直したところ、*.pages.dev は本番 SEO 運用を前提に設計されていない(プレビュー環境向けの位置づけ)ことが、改めてはっきりと書かれていました。_headers で noindex を外すこと自体は技術的には可能でも、Cloudflare 側がいつ仕様を変えても文句は言えない立場で本番運用を続けることになります。

ここで上位方針が動きました。

「これから SEO 運用を本気で前提にするなら、共有サブドメインのまま戦うのは筋が悪い」

この一文が、判断軸として一番大きかったです。_headers の対処はあくまで応急処置で、長期で読者に届けるための地盤としては不十分。*.pages.dev で得られた検索評価は、後から独自ドメインに引っ越そうとしたときに 100% は引き継げない可能性があります。早ければ早いほど引っ越しのダメージは小さい。それなら、保留を撤回して今のうちに独自ドメインへ移す方が、後の自分が楽になります。

最終的に、shikuminotane.com を Cloudflare Registrar で取得しました(年1,400円程度)。

正直に書くと、CEO参謀から提案されていた体験設計とは違う選択になりました。元の体験設計は「自分で稼いだ初収益で独自ドメインを買う」という流れで、それ自体はとても好きな設計でした。ただ、「読者にちゃんと届く」という機能性が成立していない状態でその美学にこだわっても、誰の役にも立ちません。今回は機能性(読者に届くこと)を最優先する判断をしました。

取得後の移行作業は、以下の順で進めました。

  1. Cloudflare Registrar で shikuminotane.com を取得(5/3 時点で年間1,400円程度)
  2. Cloudflare Pages の「Custom domains」で shikuminotane.comwww.shikuminotane.com を追加し、DNS レコード(CNAME)が自動設定されることを確認
  3. astro.config.mjssitehttps://shikuminotane.com に更新(サイトマップ・OGP・canonical の URL がここから生成されるため必須)
  4. blog/public/_redirects に旧 *.pages.dev から新ドメインへの 301 ルールを追加(https://shikumi-no-tane-v6.pages.dev/* https://shikuminotane.com/:splat 301
  5. デプロイ後、curl -I https://shikumi-no-tane-v6.pages.dev/blog/... で 301 が返り、Location が新ドメインを指していることを確認
  6. Search Console で shikuminotane.com を新プロパティとして追加し、所有権確認(Cloudflare DNS なら自動で確認できる)
  7. 旧プロパティ(shikumi-no-tane-v6.pages.dev)から新プロパティへ「アドレス変更ツール」を実行
  8. 新プロパティ側でサイトマップ https://shikuminotane.com/sitemap-index.xml を送信
  9. 内部リンク・OGP 画像 URL・記事内ハードコード URL の点検(grep で shikumi-no-tane-v6.pages.dev を全件洗い出し)

これから Cloudflare Pages で本気の SEO 運用を始める非エンジニアへ、自分の体験から伝えたいことを3点だけまとめておきます。

  1. 最初から独自ドメインを取る(年1,400円程度)。*.pages.dev で書き溜めてから引っ越すと、検索評価の引き継ぎロスと移行作業の二重負担になります
  2. 公式仕様(特にデフォルト挙動の項目)は最初に1回読む。X-Robots-Tag: noindex のような重要仕様は、ドキュメントに必ず書いてあります
  3. 一人で判断しきれない方針転換は、第三者目線(AIエージェントでも、人でも)に必ず相談する。「保留にしようとしていた選択を撤回する」判断は、自分一人だと感情に寄りがちです

SEO運用前提で取得を決めた本音

Cloudflare 公式が *.pages.dev での本気の SEO 運用を推奨していない、という情報を見た瞬間、独自ドメインを取得すると腹をくくりました。

正直、ここまで「0円運用」というテーマに自分自身がこだわっていたのは確かです。固定費を増やさずに副業ブログを続ける検証を、もう少し続けたい気持ちもありました。

ただ、読まれない記事を量産しても意味がない。SEO で本気に戦うなら、共有サブドメインのまま無料で粘ることに合理性がない、と頭を切り替えました。

結果、迷いが1つ減って、むしろ前に進みやすくなった感覚があります。年1,400円という金額は、これからの自分の本気度を維持するための投資としては十分安い。このまま、SEO 運用フェーズを突き進んでいきたいと思います。

あわせて読みたい

この記事が役に立ったら

同じ悩みを持つ方に届くよう、シェアしていただけると嬉しいです。

次に読む

おおばこ

物流 x AI自動化ブロガー

非エンジニアの会社員。GASとAIで日々の仕事を改善中。 「自分にもできた」を同じ立場の人に届けたいと思い、このブログを始めました。

プロフィール詳細 →