ドラフトモード
Pagesドキュメントとデータフェッチングドキュメントで、getStaticProps
とgetStaticPaths
を使用してビルド時にページをプリレンダリングする方法(静的生成)について説明しました。
静的生成は、ヘッドレスCMSからデータをフェッチするページに有用です。しかし、ヘッドレスCMSでドラフトを作成し、すぐにページでプレビューしたい場合は理想的ではありません。Next.jsにビルド時ではなくリクエスト時にページをレンダリングし、公開コンテンツではなくドラフトコンテンツをフェッチしてほしいでしょう。Next.jsにこの特定のケースでのみ静的生成をバイパスしてほしいはずです。
Next.jsには、この問題を解決するドラフトモードという機能があります。以下にその使用方法を説明します。
ステップ1:APIルートの作成とアクセス
Next.jsのAPIルートに馴染みがない場合は、まずAPIルートのドキュメントを確認してください。
まず、APIルートを作成します。名前は任意です - 例えばpages/api/draft.ts
このAPIルートで、レスポンスオブジェクトにsetDraftMode
を呼び出す必要があります。
これにより、ドラフトモードを有効にするためのCookieが設定されます。このCookieを含む後続のリクエストは、静的に生成されたページの動作を変更するドラフトモードをトリガーします。
ブラウザから手動でテストするために、以下のようなAPIルートを作成できます:
ブラウザの開発者ツールで/api/draft
にアクセスすると、__prerender_bypass
という名前のCookieを含むSet-Cookie
レスポンスヘッダーに気づくでしょう。
ヘッドレスCMSから安全にアクセスする
実際には、ヘッドレスCMSから_安全に_このAPIルートを呼び出したいでしょう。具体的な手順は使用しているヘッドレスCMSによって異なりますが、以下は一般的な手順です。
これらの手順は、使用しているヘッドレスCMSがカスタムドラフトURLの設定をサポートしていることを前提としています。サポートしていない場合でも、このメソッドをドラフトURLのセキュリティに使用できますが、ドラフトURLを手動で構築およびアクセスする必要があります。
まず、任意のトークンジェネレーターを使用してシークレットトークン文字列を作成します。このシークレットは、Next.jsアプリとヘッドレスCMS間でのみ知られます。このシークレットにより、CMSにアクセスできない人がドラフトURLにアクセスするのを防ぎます。
次に、ヘッドレスCMSがカスタムドラフトURLの設定をサポートしている場合、以下をドラフトURLとして指定します。これは、ドラフトAPIルートがpages/api/draft.ts
に配置されていることを前提としています。
<your-site>
はデプロイメントドメインに置き換えます。<token>
は生成したシークレットトークンに置き換えます。<path>
は表示したいページのパスです。/posts/foo
を表示したい場合は、&slug=/posts/foo
を使用します。
ヘッドレスCMSによっては、ドラフトURLに変数を含めることができ、<path>
をCMSのデータに基づいて動的に設定できます:&slug=/posts/{entry.fields.slug}
最後に、ドラフトAPIルートで:
- シークレットが一致し、
slug
パラメータが存在することを確認します(存在しない場合、リクエストは失敗する必要があります)。 res.setDraftMode
を呼び出します。- ブラウザを
slug
で指定されたパスにリダイレクトします。(次の例では307リダイレクトを使用しています)。
成功した場合、ブラウザは表示したいパスにドラフトモードCookieと共にリダイレクトされます。
ステップ2:getStaticProps
の更新
次のステップは、ドラフトモードをサポートするためにgetStaticProps
を更新することです。
getStaticProps
があるページに、(res.setDraftMode
を介して)Cookieが設定されている状態でリクエストすると、getStaticProps
は(ビルド時ではなく)リクエスト時に呼び出されます。
さらに、context.draftMode
がtrue
であるcontext
オブジェクトと共に呼び出されます。
ドラフトAPIルートでres.setDraftMode
を使用したため、context.draftMode
はtrue
になります。
getStaticPaths
も使用している場合、context.params
も利用可能です。
ドラフトデータのフェッチ
context.draftMode
に基づいて異なるデータをフェッチするようにgetStaticProps
を更新できます。
例えば、ヘッドレスCMSにドラフト投稿用の異なるAPIエンドポイントがあるかもしれません。その場合、以下のようにAPIエンドポイントのURLを変更できます:
以上です!ヘッドレスCMSから、または手動でドラフトAPIルート(secret
とslug
付き)にアクセスすると、ドラフトコンテンツを表示できるはずです。ドラフトを公開せずに更新した場合も、ドラフトを表示できるはずです。
ヘッドレスCMSでドラフトURLを設定するか、手動でアクセスすれば、ドラフトを表示できます。
さらに詳しく
ドラフトモードCookieのクリア
デフォルトでは、ドラフトモードセッションはブラウザを閉じると終了します。
ドラフトモードCookieを手動でクリアするには、setDraftMode({ enable: false })
を呼び出すAPIルートを作成します:
次に、/api/disable-draft
にリクエストを送信してAPIルートを呼び出します。next/link
を使用してこのルートを呼び出す場合、プリフェッチ時に誤ってCookieを削除しないよう、prefetch={false}
を渡す必要があります。
getServerSideProps
で動作
ドラフトモードはgetServerSideProps
で動作し、context
オブジェクトのdraftMode
キーとして利用可能です。
補足: ドラフトモード使用時は
Cache-Control
ヘッダーを設定しないでください。代わりにISRの使用をお勧めします。
APIルートで動作
APIルートは、リクエストオブジェクトのdraftMode
にアクセスできます。例:
next build
ごとにユニーク
next build
を実行するたびに、新しいバイパスCookieの値が生成されます。
これにより、バイパスCookieを推測できないことを保証します。
補足: HTTPでドラフトモードをローカルでテストするには、ブラウザでサードパーティCookieとローカルストレージへのアクセスを許可する必要があります。