WIPこの記事は追記・更新される可能性があります。

「記事の順番待ちで404」を滅ぼす!Next.jsで未公開記事を「公開準備中(noindex)」にしてリンク切れを防ぐ運用ハック

Design Ops / 設計・制作

#Next.js · #ブログ運用 · #Design Ops · #個人開発 · #SEO · #フロントエンド · #Vercel

公開
更新

「記事の順番待ちで404」を滅ぼす!Next.jsで未公開記事を「公開準備中(noindex)」にしてリンク切れを防ぐ運用ハック

ブログをアジャイルに爆速更新していると、地味に発生するのが 「リンク切れ(404 Not Found)」 です。

特に、まとめ記事(ハブ)を先に直したり、関連記事をランダム順で書いていくと、

「ハブからリンクを張ったのに、移動先の個別記事がまだ本番に無くて404になった!^^;」

という事態が起こりがちでした。

「ブランチを切って PR を作って、プレビューで確認してからマージすれば?」

……という正論もあるのですが、個人開発のブログ運用でそれを毎記事やると、手続きがめんどくさすぎて執筆の爆速スピードが死にます(#^ω^)。

そこで今回、main 一本の快適さを維持したまま、未公開・公開日前の記事を 404 にせず「公開準備中」UI で通す仕組み を Next.js 側に組み込みました。


課題:ブランチ運用は重い、でも404は出したくない

個人開発のブログ運用で叶えたい条件は次の3点でした。

  1. main 一本でガシガシ push したい(ブランチ切替や PR の手間をゼロに)
  2. ハブや関連記事からのフライングリンクで 404 を出したくない
  3. 薄いプレースホルダーを Google にインデックスさせたくない(低品質判定リスクの回避)

WordPress などだと「下書き=見えない/404」が標準寄りで、「非公開=アクセス不能」という固定観念に縛られがちです。

でも静的寄り(Next.js + Vercel)の個人運用では、「URL の箱だけ先に用意して、中身がまだなら『準備中』と出す」 方が、はるかにストレスフリーでした。


判定の芯:isPostPublicOnSite

実装のキモは、すでにあった公開判定をページ表示にも広げたことです。

// lib/posts.ts(概念)
isPostPublicOnSite(post) =
  post.published && !isPostFutureDated(post)
  • published: true かつ date が東京時間の「今日」以前 → 本番で本文公開
  • published: false / draft 相当、または未来の date → 本番では「公開準備中」

TOP・カテゴリ一覧・サイトマップは、もともとこの判定で 載せていない ので、今回の改修は「直 URL を踏んだとき」の体験を揃える話です。

generateStaticParams は全記事メタ(getAllPostMetas)からルートを生やすので、未来日記事も /blog/<slug> 自体はビルド時点で存在する、という前提にしています。


やったこと:ページ側の3点セット

主戦場は app/blog/[slug]/page.tsx です。

1. 本番だけ「公開準備中」UI

!isPostPublicOnSite(post) かつ 本番(NODE_ENV !== 'development' のとき、本文(MDX)を描画せず、軽いプレースホルダーを返します。

  • タイトルは出す(ハブから来た人が「この記事だ」と分かる)
  • published: true で未来日なら 公開予定日 も出す
  • 本文・excerpt・ヒーロー画像は出さない

文言はシンプルに「この記事は現在公開準備中です。」だけ。最初は「一覧や sitemap には載せていません/noindex です」まで書いていたのですが、読者向けには情報過多だったので、実装メモとしてコードコメントに退避しました。

2. メタデータもネタバレしない+noindex

公開前は次のようにしています。

  • robots: { index: false, follow: false }
  • description は固定の「公開準備中」文
  • excerpt や OGP 画像は付けない(タイトル以外のネタバレ防止)
// generateMetadata のイメージ(本番の公開前)
if (!isPostPublicOnSite(post)) {
  return {
    title: `${post.title} | ほしもちレコード`,
    description: "この記事は現在公開準備中です。",
    robots: { index: false, follow: false },
  };
}

これで、薄いプレースホルダーが検索結果に並ぶリスクを抑えつつ、URL 自体は生きたままにできます。

3. ローカル next dev では全文プレビュー

開発中は準備中画面に落とさず、本文をそのまま表示します(公開日前・下書きも確認しやすい)。

dev では一覧にも下書き/未来日が混ざる既存仕様があるので、「本番の顔」と「執筆中の顔」を分けた形です。


運用ルール:未来日リンクを容赦なく張る

コードとセットで、執筆ルール(.cursor/rules/blog-writing.mdc)も更新しました。

  • published: true +未来の date先に push してよい
  • ハブや相互リンクは 本物の /blog/<slug> を先に書いてよい
  • 本番の直 URL は準備中画面 → 公開日当日のデプロイ後に本文へ切り替わる

実際、この改修の直後に 8/21〜9/6 分のリリース確定記事をまとめて push し、ハブから契約自衛チェックリストなどへのリンクも本物 URL のまま載せました。リンク切れを気にして「公開予定」とテキストだけにする、みたいな回避が要らなくなったのがいちばん大きいです。


導入して実感したメリット

執筆の順番・依存関係から解放された

ハブを先に直そうが、個別を後から書こうが、先に push されていれば 404 にならない
「どっちを先にデプロイすべきか……」が消えます。

main 一本のまま SEO の防衛線だけ張れる

ブランチ/PR を増やさなくても、

  • 一覧・sitemap 非掲載
  • 直 URL は準備中 UI
  • noindex

で、読者体験と検索向けの両方を守れる。

アジャイル執筆(MVP リリース)との相性が良い

思いついた関連記事の URL をハブに先に書いて、中身は公開日に合わせる、という流れが自然に回ります。執筆 OS の話は AI対話×MVP高速リリース にも書いています。


まとめ:運用ストレスはコードで握りつぶす

チーム向けの厳密なブランチ運用を、そのまま個人ブログに持ち込むと、ただの摩擦になりがちです。

「404 を出さない」「薄いページをインデックスさせない」 をコードで先に張ったうえで、自分の運用コストを削る。

今回の「公開準備中(noindex)」は、そのための小さな防衛線でした。楽ちん運用で記事とハブを同時に育てたい個人開発ブロガー向けの、かなりおすすめパターンです(^^)

サイトの改修ログとしては、【ハブ】star-moti.com 改修ログまとめ にも残しておきます。

(本文 随時追記予定)