症状

公開前の記事3本に draft: true を付けて置いておいた。トップの一覧にもRSSにも出ない。下書きとして機能しているように見える。

ところが、個別URLを直接叩くと普通に表示される。さらにsitemapを見ると、ドラフトのURLがしっかり載っていた。つまり「見せていないつもりの記事」が、検索エンジンには案内済みという状態。

検証環境

create astro のblogテンプレートから立ち上げた静的ブログ(Astro 7.2.4)。記事はコンテンツコレクション管理で、frontmatterに draft フラグを追加した構成。

原因候補と確認したこと

最初の想定は「draftフラグの書き方を間違えた」。でもfrontmatterは正しい。一覧とRSSからはちゃんと消えている。

そこで除外処理がどこに入っているかを数えた。一覧ページ: ある。RSS: ある。個別ページの動的ルート: ない。sitemap: 生成されたページを全部拾うだけなので、当然ない。

実際の原因

テンプレートのdraft除外が「一覧系」にしか入っていなかった。個別ページを作る動的ルート([...slug].astro)の getStaticPaths は全記事分のページを生成していて、sitemapインテグレーションはその生成結果をそのまま反映する。

「下書き」という機能があるのではなく、「一覧から隠す処理」が2箇所に書いてあっただけ、というのが正体。

解決方法と解決確認

動的ルート側の getStaticPaths に本番ビルド時のみのdraft除外を追加した。開発サーバーでは従来どおり閲覧できるようにして、レビュー用途は残した。

再ビルドしてdistを走査するとdraft記事3本が消え、sitemapからもURLが消えた。開発環境では3本とも表示できることも確認。

今回得たEXP

「一覧に出ない」と「公開されない」は別物。draftのような除外系の機能は、出口の数(一覧・RSS・個別ページ・sitemap)を数えて、全部で除外されているか確認してから信じる。

現場でいうと、立入禁止の看板を正門にだけ立てて、裏口と通用口が開けっぱなしになっていた状態。囲いは出入口の数だけ点検する。

ちなみにこの漏れを見つけたのは、記事ドラフトを書かせていたAI相棒だった。「draftなのにsitemapに載る」と自分で気づいて直してきた。囲いの点検は任せられる時代になっている。