プレビューモード
注意: この機能はドラフトモードに置き換えられています。
例
- WordPress の例 (デモ)
- DatoCMS の例 (デモ)
- TakeShape の例 (デモ)
- Sanity の例 (デモ)
- Prismic の例 (デモ)
- Contentful の例 (デモ)
- Strapi の例 (デモ)
- Prepr の例 (デモ)
- Agility CMS の例 (デモ)
- Cosmic の例 (デモ)
- ButterCMS の例 (デモ)
- Storyblok の例 (デモ)
- GraphCMS の例 (デモ)
- Kontent の例 (デモ)
- Umbraco Heartcore の例 (デモ)
- Plasmic の例 (デモ)
- Enterspeed の例 (デモ)
- Makeswift の例 (デモ)
ページのドキュメントとデータフェッチングのドキュメントで、getStaticProps
とgetStaticPaths
を使用してビルド時にページを事前レンダリングする(静的生成)方法について説明しました。
静的生成は、ヘッドレスCMSからデータを取得するページに役立ちます。しかし、ヘッドレスCMS上で下書きを作成し、そのドラフトをすぐにページでプレビューしたい場合は理想的ではありません。このような場合、ユーザーはNext.jsにビルド時ではなくリクエスト時にページをレンダリングし、公開されたコンテンツではなくドラフトコンテンツをフェッチしてほしいと考えます。この特定の場合のみ、Next.jsに静的生成をバイパスしてほしいのです。
Next.jsにはプレビューモードと呼ばれる機能があり、この問題を解決します。その使用方法を以下に説明します。
ステップ1: プレビューAPIルートの作成とアクセス
Next.jsのAPIルートに慣れていない場合は、まずAPIルートのドキュメントを確認してください。
まず、プレビューAPIルートを作成します。名前は任意です - 例えばpages/api/preview.js
(TypeScriptを使用する場合は.ts
)。
このAPIルートでは、レスポンスオブジェクトでsetPreviewData
を呼び出す必要があります。setPreviewData
の引数はオブジェクトである必要があり、これはgetStaticProps
で使用できます(後述)。現時点では、{}
を使用します。
res.setPreviewData
はブラウザにいくつかのCookieを設定し、プレビューモードをオンにします。これらのCookieを含むNext.jsへのリクエストはすべてプレビューモードと見なされ、静的に生成されたページの動作が変更されます(詳細は後述)。
ブラウザから手動でテストするには、以下のようなAPIルートを作成します:
ブラウザの開発者ツールで/api/preview
にアクセスすると、このリクエストで__prerender_bypass
と__next_preview_data
のCookieが設定されることに気づくでしょう。
ヘッドレスCMSから安全にアクセスする
実際には、ヘッドレスCMSから_安全に_このAPIルートを呼び出したいと思うでしょう。具体的な手順は使用しているヘッドレスCMSによって異なりますが、次のような一般的な手順を取ることができます。
これらの手順は、使用しているヘッドレスCMSがカスタムプレビューURLの設定をサポートしていることを前提としています。サポートしていない場合でも、このメソッドを使用してプレビューURLを保護できますが、プレビューURLを手動で構築およびアクセスする必要があります。
まず、選択したトークンジェネレーターを使用して、シークレットトークン文字列を作成します。このシークレットは、Next.jsアプリとヘッドレスCMSのみが知っているものです。このシークレットにより、CMSにアクセスできない人がプレビューURLにアクセスできないようにします。
次に、ヘッドレスCMSがカスタムプレビューURLの設定をサポートしている場合は、以下のようなプレビューURLを指定します。これは、プレビューAPIルートがpages/api/preview.js
に配置されていることを前提としています。
<your-site>
はデプロイメントドメインに置き換えます。<token>
は生成したシークレットトークンに置き換えます。<path>
はプレビューするページのパスです。/posts/foo
をプレビューする場合は、&slug=/posts/foo
を使用します。
ヘッドレスCMSによっては、プレビューURLで変数を含めることができるため、<path>
はCMSのデータに基づいて動的に設定できます:&slug=/posts/{entry.fields.slug}
最後に、プレビューAPIルートで以下を行います:
- シークレットが一致し、
slug
パラメータが存在することを確認します(存在しない場合、リクエストは失敗する必要があります)。 res.setPreviewData
を呼び出します。- ブラウザを
slug
で指定されたパスにリダイレクトします。(以下の例では307リダイレクトを使用しています)。
成功した場合、ブラウザはプレビューするパスにリダイレクトされ、プレビューモードのCookieが設定されます。
ステップ2: getStaticProps
の更新
次のステップは、プレビューモードをサポートするために getStaticProps
を更新することです。
プレビューモードのクッキーが設定された(res.setPreviewData
経由で)ページをリクエストすると、getStaticProps
はビルド時ではなく、リクエスト時に呼び出されます。
さらに、以下のプロパティを持つ context
オブジェクトと共に呼び出されます:
context.preview
はtrue
になります。context.previewData
は、setPreviewData
に使用された引数と同じになります。
プレビューAPIルートで res.setPreviewData({})
を使用したため、context.previewData
は {}
になります。必要に応じて、これを使用してプレビューAPIルートからのセッション情報を getStaticProps
に渡すことができます。
getStaticPaths
も使用している場合、context.params
も利用可能になります。
プレビューデータの取得
context.preview
や context.previewData
に基づいて異なるデータを取得するように getStaticProps
を更新できます。
例えば、ヘッドレスCMSには下書き記事用の異なるAPIエンドポイントがある場合があります。その場合、context.preview
を使用してAPIエンドポイントのURLを以下のように変更できます:
それで完了です!ヘッドレスCMSから、または手動で、secret
と slug
を含むプレビューAPIルートにアクセスすれば、プレビューコンテンツを表示できるはずです。下書きを更新して公開しない場合も、下書きをプレビューできるはずです。
ヘッドレスCMSでプレビューURLとして設定するか、手動でアクセスすれば、プレビューを表示できるはずです。
さらに詳しく
補足: レンダリング中、
next/router
はisPreview
フラグを公開します。詳細はルーターオブジェクトのドキュメントを参照してください。
プレビューモードの持続期間を指定
setPreviewData
は、オプションのセカンドパラメータとしてオプションオブジェクトを取ります。以下のキーを受け入れます:
maxAge
: プレビューセッションの持続時間(秒単位)を指定します。path
: クッキーを適用するパスを指定します。デフォルトは/
で、すべてのパスでプレビューモードを有効にします。
プレビューモードのクッキーをクリア
デフォルトでは、プレビューモードのクッキーに有効期限は設定されないため、ブラウザを閉じるまでプレビューセッションは続きます。
プレビューモードのクッキーを手動でクリアするには、clearPreviewData()
を呼び出すAPIルートを作成します:
次に、APIルートを呼び出すために /api/clear-preview-mode-cookies
にリクエストを送信します。next/link
を使用してこのルートを呼び出す場合、リンクプリフェッチ中に clearPreviewData
が呼ばれるのを防ぐために、prefetch={false}
を渡す必要があります。
setPreviewData
呼び出し時にパスが指定された場合、clearPreviewData
にも同じパスを渡す必要があります:
previewData
のサイズ制限
setPreviewData
にオブジェクトを渡し、getStaticProps
で利用可能にできます。ただし、データはクッキーに保存されるため、サイズ制限があります。現在、プレビューデータは2KBに制限されています。
getServerSideProps
でも動作
プレビューモードは getServerSideProps
でも動作します。preview
と previewData
を含む context
オブジェクトでも利用可能になります。
補足: プレビューモード使用時は
Cache-Control
ヘッダーを設定すべきではありません。代わりに、ISR の使用をお勧めします。
APIルートでの動作
APIルートは、リクエストオブジェクト下の preview
と previewData
にアクセスできます。例:
next build
ごとにユニーク
バイパスクッキー値と previewData
を暗号化するプライベートキーは、next build
完了時に変更されます。
これにより、バイパスクッキーを推測できないようにします。
補足: HTTPでプレビューモードをローカルでテストするには、ブラウザでサードパーティのクッキーとローカルストレージへのアクセスを許可する必要があります。