ドラフトモード
ドラフトモードを使用すると、ヘッドレスCMSのドラフトコンテンツをNext.jsアプリケーションでプレビューできます。これは、ビルド時に生成される静的ページにとって便利で、サイト全体を再構築することなく動的レンダリングに切り替えて、ドラフトの変更を確認できます。
このページでは、ドラフトモードを有効にして使用する方法を説明します。
ステップ1: ルートハンドラーの作成
ルートハンドラーを作成します。例えば、app/api/draft/route.ts
のように、任意の名前を付けることができます。
export async function GET(request: Request) {
return new Response('')
}
次に、draftMode
関数をインポートし、enable()
メソッドを呼び出します。
import { draftMode } from 'next/headers'
export async function GET(request: Request) {
const draft = await draftMode()
draft.enable()
return new Response('Draft mode is enabled')
}
これにより、ドラフトモードを有効にするためのクッキーが設定されます。このクッキーを含むその後のリクエストはドラフトモードをトリガーし、静的に生成されたページの動作を変更します。
/api/draft
にアクセスし、ブラウザの開発者ツールで確認することで、これを手動でテストできます。__prerender_bypass
という名前のクッキーを持つSet-Cookie
レスポンスヘッダーに注目してください。
ステップ2: Headless CMSからルートハンドラーにアクセスする
これらの手順は、使用しているヘッドレスCMSがカスタムドラフトURLの設定をサポートしていることを前提としています。サポートしていない場合でも、この方法でドラフトURLを保護できますが、ドラフトURLを手動で構築してアクセスする必要があります。具体的な手順は、使用しているヘッドレスCMSによって異なります。
ヘッドレスCMSからルートハンドラーに安全にアクセスするには
- 任意のトークンジェネレーターを使用してシークレットトークン文字列を作成します。このシークレットは、Next.jsアプリケーションとヘッドレスCMSのみが知っているものとなります。
- ヘッドレスCMSがカスタムドラフトURLの設定をサポートしている場合、ドラフトURLを指定します(これは、ルートハンドラーが
app/api/draft/route.ts
に配置されていることを前提としています)。例:
https://<your-site>/api/draft?secret=<token>&slug=<path>
<your-site>
はデプロイされたドメインである必要があります。<token>
は、生成したシークレットトークンに置き換える必要があります。<path>
は、表示したいページのパスである必要があります。/posts/one
を表示したい場合は、&slug=/posts/one
を使用してください。ヘッドレスCMSによっては、ドラフトURLに変数を組み込むことで、CMSのデータに基づいて
<path>
を動的に設定できる場合があります。例:&slug=/posts/{entry.fields.slug}
- ルートハンドラーで、シークレットが一致し、
slug
パラメーターが存在することを確認し(存在しない場合、リクエストは失敗するはずです)、draftMode.enable()
を呼び出してクッキーを設定します。その後、ブラウザをslug
で指定されたパスにリダイレクトします。
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
// Parse query string parameters
const { searchParams } = new URL(request.url)
const secret = searchParams.get('secret')
const slug = searchParams.get('slug')
// Check the secret and next parameters
// This secret should only be known to this Route Handler and the CMS
if (secret !== 'MY_SECRET_TOKEN' || !slug) {
return new Response('Invalid token', { status: 401 })
}
// 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(slug)
// If the slug doesn't exist prevent draft mode from being enabled
if (!post) {
return new Response('Invalid slug', { status: 401 })
}
// Enable Draft Mode by setting the cookie
const draft = await draftMode()
draft.enable()
// Redirect to the path from the fetched post
// We don't redirect to searchParams.slug as that might lead to open redirect vulnerabilities
redirect(post.slug)
}
成功した場合、ブラウザはドラフトモードのクッキーが設定された状態で、表示したいパスにリダイレクトされます。
ステップ3: ドラフトコンテンツのプレビュー
次のステップは、ページを更新してdraftMode().isEnabled
の値を確認することです。
クッキーが設定されたページをリクエストした場合、データは(ビルド時ではなく)リクエスト時にフェッチされます。
さらに、isEnabled
の値はtrue
になります。
// page that fetches data
import { draftMode } from 'next/headers'
async function getData() {
const { isEnabled } = await draftMode()
const url = isEnabled
? 'https://draft.example.com'
: 'https://production.example.com'
const res = await fetch(url)
return res.json()
}
export default async function Page() {
const { title, desc } = await getData()
return (
<main>
<h1>{title}</h1>
<p>{desc}</p>
</main>
)
}
ヘッドレスCMSから(secret
とslug
を使って)ドラフトルートハンドラーにアクセスするか、URLを使って手動でアクセスすると、ドラフトコンテンツが表示されるはずです。また、公開せずにドラフトを更新した場合も、ドラフトを閲覧できるはずです。
お役に立ちましたか?