microCMSはヘッドレスCMSであり、APIでJSONを返すだけで、HTMLのレンダリング機能を持たない。下書きコンテンツが公開後にサイト上でどう表示されるかを確認するには、Next.js側に「下書きデータを受け取って本番と同じレイアウトで描画するモード」を実装する必要がある。
ISRで静的生成しているページで draftMode() や cookies() を isEnabled の分岐外(=関数のトップレベルなど)で呼ぶと、Next.jsはそのページを動的ページと判定する。結果、全リクエストでサーバー実行され、ビルド時生成のHTMLキャッシュが使われなくなる。isEnabled === true の分岐内に閉じ込めれば、isEnabled === false 時は静的生成済みHTMLがそのまま返る。
- microCMSの画面プレビューボタンは
/api/draft?secret=xxx&contentId=yyy&draftKey=zzz&type=articleにリクエストを送る。/api/draftRoute Handlerはこのリクエストを受け、secretを環境変数と照合し、パラメータを検証したうえでdraftMode().enable()を実行し、draftKeyをCookieに保存してからプレビュー対象ページへリダイレクトする。 - ページ側では
draftMode().isEnabled === trueの分岐内でのみcookies()でdraftKeyを取得し、microCMSの下書きAPIにリクエストを送る。
Preview環境にパスワード保護をかけていると、/api/draft からプレビューページへのリダイレクトもパスワード入力画面に遮られる。リダイレクトのレスポンスヘッダーに x-vercel-protection-bypass(保護を迂回するためのシークレット)と x-vercel-set-bypass-cookie: true(後続リクエストにもCookie経由で迂回を継続させるフラグ)を付けると、パスワード入力画面を経由せずプレビューページに到達できる。
httpOnly: true、secure: true(本番)、sameSite: 'lax'、maxAge: 86400(24時間)。sameSite はブラウザごとにデフォルト値が異なるため明示指定する。
ruby -rsecurerandom -e 'puts SecureRandom.hex(20)' で40文字の16進数文字列を生成。このトークンは /api/draft エンドポイントへのアクセスを制限するためのもので、これがないとURLを知っている誰でも draftMode を有効化できてしまう。40文字の16進数は総当たり攻撃に対して十分な探索空間(160bit)がある。ただし公開前のIR資料など漏洩が致命的なコンテンツを扱う場合はバイト数を増やす。