Skip to content

Instantly share code, notes, and snippets.

@kobitoDevelopment
Created February 8, 2026 15:55
Show Gist options
  • Select an option

  • Save kobitoDevelopment/b0dd2de70043bde4fb3719330ec056f2 to your computer and use it in GitHub Desktop.

Select an option

Save kobitoDevelopment/b0dd2de70043bde4fb3719330ec056f2 to your computer and use it in GitHub Desktop.

Next.jsでmicroCMSの下書き機能を実装する際の注意点

前提

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/draft Route Handlerはこのリクエストを受け、secretを環境変数と照合し、パラメータを検証したうえで draftMode().enable() を実行し、draftKeyをCookieに保存してからプレビュー対象ページへリダイレクトする。
  • ページ側では draftMode().isEnabled === true の分岐内でのみ cookies() でdraftKeyを取得し、microCMSの下書きAPIにリクエストを送る。

Vercel Password Protectionとの共存

Preview環境にパスワード保護をかけていると、/api/draft からプレビューページへのリダイレクトもパスワード入力画面に遮られる。リダイレクトのレスポンスヘッダーに x-vercel-protection-bypass(保護を迂回するためのシークレット)と x-vercel-set-bypass-cookie: true(後続リクエストにもCookie経由で迂回を継続させるフラグ)を付けると、パスワード入力画面を経由せずプレビューページに到達できる。

Cookieの設定

httpOnly: truesecure: true(本番)、sameSite: 'lax'maxAge: 86400(24時間)。sameSite はブラウザごとにデフォルト値が異なるため明示指定する。

secretトークン

ruby -rsecurerandom -e 'puts SecureRandom.hex(20)' で40文字の16進数文字列を生成。このトークンは /api/draft エンドポイントへのアクセスを制限するためのもので、これがないとURLを知っている誰でも draftMode を有効化できてしまう。40文字の16進数は総当たり攻撃に対して十分な探索空間(160bit)がある。ただし公開前のIR資料など漏洩が致命的なコンテンツを扱う場合はバイト数を増やす。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment