LPの公開を2段階ゲートで守る — winner + noindex
LP PoCを量産する運用では、「検証中のLPが誤って検索結果に出る」事故 が一番怖い。 未完成の訴求が露出するとブランドが薄れ、計測ノイズも増える。 LeapLensでは、frontmatterの単一フラグではなく2つの条件のANDで公開判定している。
単一フラグだと事故が起きる
最初は noindex: true をfrontmatterのデフォルトにし、公開時に false に書き換える方式を考えた。
だが1行のミスで露出してしまうのが怖い。コードレビューで気づけば良いが、PoCを高速で回す現場で常に通るとは限らない。
statusとnoindexの二段階
そこで状態管理用の status を別軸で導入した:
type LpStatus = "draft" | "running" | "winner" | "archived";
そして公開判定:
export const isPubliclyDiscoverable = (data) =>
data.status === "winner" && data.noindex === false;
draft: 書き始めrunning: 検証中(常にnoindex)winner: 採用決定。ここで初めてnoindex: falseを意図的に書くarchived: 終わった検証(再びnoindex)
status がwinner以外なら、たとえfrontmatterに noindex: false と書いても 強制的にnoindexが出る。
逆に status: winner でも noindex のデフォルトtrueのままなら公開されない。
二段階の意図 が必要なので、片方の事故では出ない。
三重防壁
それでも漏れることはある。だから多層化する:
| レイヤ | 仕掛け |
|---|---|
| Page meta | <meta name="robots" content="noindex,nofollow"> |
| robots.txt | Disallow: /lps/ |
| Vercel header | X-Robots-Tag: noindex, nofollow (vercel.json) |
この3つはすべて同時に効くので、どれかが抜けても残りで守れる。
公開フロー
実際の手順:
pnpm new:lp <slug>で雛形を作成。status: draftとnoindex: trueが入るstatus: runningに変更して検証開始(noindexはそのまま)- 採用決定したら
status: winner+noindex: falseを 両方 書き換え - それで初めてインデックス対象になる
なぜ「採用済」だけが公開対象か
採用されたLPは、もはやPoCではなく 本番の訴求 として独立した価値を持つ。 それは独立URLでインデックスされる意味がある。 逆に「検証中」「終了」は、本来仮置きや学習素材なので、検索結果にあるべきではない。
まとめ
- 1つのフラグでは事故が起きやすい
statusとnoindexの2つの軸をANDで要求すると、意図的な行動が必須になる- さらに3重のnoindex (meta / robots / header) で漏れを防ぐ
- 状態が言語化されているので、レビューも自然になる
LPの量産はスピードと品質のトレードオフだが、この公開ゲートのおかげで、安心してドラフトをrepoに置けるようになった。