WIP — この記事は追記・更新される可能性があります。
「記事の順番待ちで404」を滅ぼす!Next.jsで未公開記事を「公開準備中(noindex)」にしてリンク切れを防ぐ運用ハック
#Next.js · #ブログ運用 · #Design Ops · #個人開発 · #SEO · #フロントエンド · #Vercel
公開
更新
「記事の順番待ちで404」を滅ぼす!Next.jsで未公開記事を「公開準備中(noindex)」にしてリンク切れを防ぐ運用ハック
ブログをアジャイルに爆速更新していると、地味に発生するのが 「リンク切れ(404 Not Found)」 です。
特に、まとめ記事(ハブ)を先に直したり、関連記事をランダム順で書いていくと、
「ハブからリンクを張ったのに、移動先の個別記事がまだ本番に無くて404になった!^^;」
という事態が起こりがちでした。
「ブランチを切って PR を作って、プレビューで確認してからマージすれば?」
……という正論もあるのですが、個人開発のブログ運用でそれを毎記事やると、手続きがめんどくさすぎて執筆の爆速スピードが死にます(#^ω^)。
そこで今回、main 一本の快適さを維持したまま、未公開・公開日前の記事を 404 にせず「公開準備中」UI で通す仕組み を Next.js 側に組み込みました。
課題:ブランチ運用は重い、でも404は出したくない
個人開発のブログ運用で叶えたい条件は次の3点でした。
main一本でガシガシ push したい(ブランチ切替や PR の手間をゼロに)- ハブや関連記事からのフライングリンクで 404 を出したくない
- 薄いプレースホルダーを 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 改修ログまとめ にも残しておきます。
(本文 随時追記予定)