Preview Mode
注意: この機能はDraft Modeによって上書きされます。
Examples
- WordPress Example (Demo )
- DatoCMS Example (Demo )
- TakeShape Example (Demo )
- Sanity Example (Demo )
- Prismic Example (Demo )
- Contentful Example (Demo )
- Strapi Example (Demo )
- Prepr Example (Demo )
- Agility CMS Example (Demo )
- Cosmic Example (Demo )
- ButterCMS Example (Demo )
- Storyblok Example (Demo )
- GraphCMS Example (Demo )
- Kontent Example (Demo )
- Umbraco Heartcore Example (Demo )
- Plasmic Example (Demo )
- Enterspeed Example (Demo )
- Makeswift Example (Demo )
Pages ドキュメントとData Fetching ドキュメントで、getStaticProps
と getStaticPaths
を使用してビルド時にページをプレレンダリングする方法(Static Generation)について説明しました。
Static Generation はページがヘッドレス CMS から fetch データを取得するときに便利です。しかし、ヘッドレス CMS で下書きを書いて、その下書きをページですぐにpreviewしたい場合には理想的ではありません。この場合、あなたは Next.js にこれらのページを build 時間ではなく、request 時に render し、公開されたコンテンツではなく下書きのコンテンツを fetch するようにしたいでしょう。あなたはこの特定のケースだけで Next.js に Static Generation をバイ path してもらいたいのです。
Next.js は、この問題を解決するPreview モードという機能を持っています。それの使い方についての指示は以下の通りです。
Step 1: Create and access a preview API route
Next.js の API Routes に慣れていない場合は、まず API Routes ドキュメントをご覧ください。
まず、preview API routeを作成します。任意の名前を付けることができます - 例えば pages/api/preview.js
(あるいは TypeScript を使用している場合は .ts
)。
この API route では、response object でsetPreviewData
を呼び出す必要があります。setPreviewData
の引数は object であり、これはgetStaticProps
で使用できます(これについては後ほど詳しく説明します)。今のところ、我々は{}
を使用します。
export default function handler(req, res) {
// ...
res.setPreviewData({});
// ...
}
res.setPreviewData
はブラウザにいくつかのcookiesを設定し、preview モードをオンにします。これらの cookies を含む Next.js へのすべての Request は、preview モードとみなされ、静的に生成されたページの動作が変更されます(詳しくは後述します)。
以下のような API ルートを作成し、ブラウザから手動でアクセスすることで、これを手動でテストすることができます:
// simple example for testing it manually from your browser.
export default function handler(req, res) {
res.setPreviewData({})
res.end('Preview mode enabled')
}
ブラウザの開発者ツールを開いて/api/preview
にアクセスすると、__prerender_bypass
と __next_preview_data
の cookies がこの request に設定されることに気づくでしょう。
Securely accessing it from your Headless CMS
実際には、ヘッドレス CMS からこの API ルートを 安全に 呼び出すことを望むでしょう。使用しているヘッドレス CMS によって具体的なステップは異なりますが、ここにいくつかの一般的なステップを示します。
これらの手順は、使用しているヘッドレス CMS がカスタム previewURL の設定をサポートしていることを前提としています。もしサポートしていない場合でも、この method を使用して previewURL を保護することは可能ですが、手動で preview URL を構築しアクセスする必要があります。
まず、お好みのトークンジェネレーターを使用して、secret トークン stringを作成する必要があります。この secret は、あなたの Next.js app とヘッドレス CMS だけが知っています。この secret は、CMS へのアクセス権がない人々が preview URL にアクセスするのを防ぎます。
次に、ヘッドレス CMS がカスタム preview URL の設定をサポートしている場合は、次の URL を preview URL として指定します。これは、 preview API route がpages/api/preview.js
に位置していることを前提としています。
https://<your-site>/api/preview?secret=<token>&slug=<path>
<your-site>
はデプロイメントドメインであるべきです。<token>
は生成したシークレットトークンに置き換えるべきです。<path>
は、preview したいページの path であるべきです。/posts/foo
を preview したい場合は、&slug=/posts/foo
を使用するべきです。
あなたのヘッドレス CMS では、<path>
が CMS のデータに基づいて動的に設定できるように、variable を preview URL に含めることが可能かもしれません。例えば、&slug=/posts/{entry.fields.slug}
のようにします。
最後に、 preview API route で:
- secret が一致していること、そして
slug
パラメータが存在することを確認します(存在しない場合、リクエストは失敗するべきです)。 res.setPreviewData
を呼び出してください。- 次に、
slug
で指定されたパスにブラウザをリダイレクトします(以下の例では307 リダイレクト を使用しています)。
export default async (req, res) => {
// Check the secret and next parameters
// This secret should only be known to this API route and the CMS
if (req.query.secret !== "MY_SECRET_TOKEN" || !req.query.slug) {
return res.status(401).json({ message: "Invalid token" });
}
// Fetch the headless CMS to check if the provided `slug` exists
// getPostBySlug would implement the required fetching logic to the headless CMS
const post = await getPostBySlug(req.query.slug);
// If the slug doesn't exist prevent preview mode from being enabled
if (!post) {
return res.status(401).json({ message: "Invalid slug" });
}
// Enable Preview Mode by setting the cookies
res.setPreviewData({});
// Redirect to the path from the fetched post
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
res.redirect(post.slug);
};
成功すれば、ブラウザはあなたが preview モードで cookies が設定された状態で preview したい path に Redirect されます。
Step 2: Update getStaticProps
次の next ステップは、 preview モードをサポートするためにgetStaticProps
を更新することです。
もし、getStaticProps
を持つページを request し、その際に preview モードの cookies が res.setPreviewData
によってセットされた場合、getStaticProps
は request 時( build 時ではなく)で呼び出されます。
さらに、それはcontext
object で呼び出されます。その場合、次のようになります:
context.preview
はtrue
になります。context.previewData
はsetPreviewData
に使用される引数と同じになります。
export async function getStaticProps(context) {
// If you request this page with the preview mode cookies set:
//
// - context.preview will be true
// - context.previewData will be the same as
// the argument used for `setPreviewData`.
}
私たちは preview API route でres.setPreviewData({})
を使用したので、context.previewData
は{}
になります。必要であれば、この機能を使って preview API route からgetStaticProps
にセッション情報を送ることができます。
getStaticPaths
も使用している場合は、context.params
も利用可能になります。
Fetch preview データ
あなたはgetStaticProps
を更新して、context.preview
および/またはcontext.previewData
に基づいて異なるデータを fetch できます。
例えば、あなたのヘッドレス CMS は、下書きの投稿用の異なる API エンドポイントを持つかもしれません。その場合、context.preview
を使用して、以下のように API エンドポイントの URL を変更することができます:
export async function getStaticProps(context) {
// If context.preview is true, append "/preview" to the API endpoint
// to request draft data instead of published data. This will vary
// based on which headless CMS you're using.
const res = await fetch(`https://.../${context.preview ? "preview" : ""}`);
// ...
}
それで終わりです!あなたがヘッドレス CMS から、または手動で preview API route(secret
およびslug
を使用して)にアクセスすると、今では preview コンテンツを見ることができるはずです。また、公開せずにドラフトを更新すると、ドラフトを preview することができるはずです。
この URL をヘッドレス CMS の preview URL に設定するか、手動でアクセスすれば、preview を見ることができるはずです。
https://<your-site>/api/preview?secret=<token>&slug=<path>
More Details
Good to know: レンダリング中に、
next/router
はisPreview
フラグを公開します。詳細については、router object ドキュメントをご覧ください。
Preview モードの持続時間を指定してください
setPreviewData
はオプショナルな second パラメータを取ります。これは options object であるべきです。以下のキーを受け付けます:
maxAge
: preview セッションが続く number (秒単位)を指定します。path
: cookie が適用されるべき paths を指定します。default では、/
が設定され、全ての path に対して preview モードが有効になります。
setPreviewData(data, {
maxAge: 60 * 60, // The preview mode cookies expire in 1 hour
path: "/about", // The preview mode cookies apply to paths with /about
});
Preview モードの cookies をクリアする
default では、 Preview モードの cookies に有効期限の date が設定されていません。したがって、 preview セッションは、ブラウザを閉じたときに終了します。
Preview モードの cookies を手動でクリアするには、clearPreviewData()
を呼び出す API route を作成します。
export default function handler(req, res) {
res.clearPreviewData({})
}
次に、/api/clear-preview-mode-cookies
に対して request を送信して、 API Route を呼び出します。この route をnext/link
を使用して呼び出す場合、clearPreviewData
が link の prefetching 中に呼び出されるのを防ぐためにprefetch={false}
を渡す必要があります。
setPreviewData
の呼び出しで path が指定された場合、同じ path をclearPreviewData
に渡さなければなりません。
export default function handler(req, res) {
const { path } = req.query
res.clearPreviewData({ path })
}
previewData
size の制限
setPreviewData
に object を渡して、getStaticProps
で利用できるようにすることが可能です。ただし、データは cookie に保存されるため、size 制限があります。現在、preview データは 2KB に制限されています。
Works with getServerSideProps
getServerSideProps
でも preview モードが機能します。これはまた、preview
とpreviewData
を含むcontext
object でも利用可能になります。
Good to know:
Cache-Control
の header を Preview モードで使用する際に設定するべきではありません。これはバイパスできません。代わりに、ISRの使用をお勧めします。
Works with API Routes
API Routes は、request object の下でpreview
およびpreviewData
にアクセスできます。例えば:
export default function myApiRoute(req, res) {
const isPreview = req.preview;
const previewData = req.previewData;
// ...
}
Unique per next build
バイパスの cookie value と、previewData
を暗号化するためのプライベートキーは、next build
が完了すると変更されます。これにより、バイパスの cookie が推測されることはありません。
Good to know: test Preview モードをローカルの HTTP 上でテストするためには、ブラウザがサードパーティの cookies とローカルストレージへのアクセスを許可する必要があります。