
Contentful Content Preview 機能チュートリアル実践 - Next.js での実装例
はじめに
本記事では、Contentful の Content Preview 機能を使用し、下書き記事をプレビューできるアプリを構築します。
Contentful とは
Contentful は、API ファーストのヘッドレス CMS です。コンテンツの作成・管理と表示を分離することで、様々なプラットフォームやデバイスに対して柔軟にコンテンツを配信できます。
Contentful の Content Preview 機能とは
Content Preview 機能は、Contentful で作成したコンテンツを公開前にプレビューできる機能です。この機能により、編集者は下書き状態のコンテンツを実際のウェブサイトやアプリの見た目で確認できます。
対象読者
- Content Preview 機能の導入を検討している方
- Contentful を使用したヘッドレス CMS の実装経験がある方
- Next.js の基本的な知識を持つ開発者
参考
全体の構成
本記事では Preview 用アプリの例として Next.js を使用します。
Contentful 側の準備
本記事では、 Preview 機能を適用する Content model として BlogPost を作成済みであるとします。
-
Contentful コンソール にアクセス
-
Settings menu (画面上部の歯車マーク) > General settings > Space ID を控える
-
Settings menu > API keys から Content Preview API - access token を控える
-
Settings menu > Content preview で Start setup をクリック
-
以下の設定を入力
- Name: 任意 (例:
Local Development
) - Description: 任意 (例:
ローカル開発環境
) - Content types: BlogPost
- Preview URL for BlogPost:
http://localhost:3000/api/preview?secret=YOUR_PREVIEW_SECRET&id={entry.sys.id}
- Name: 任意 (例:
ローカルでの実装
プロジェクトのセットアップ
プロジェクトディレクトリを作成し、必要なライブラリをインストールします。Next.js プロジェクトの初期設定では app router を選択し作成します。
npx create-next-app@latest contentful-preview-demo
cd contentful-preview-demo
npm install contentful @contentful/rich-text-react-renderer @contentful/rich-text-types
環境変数の設定
Contentful へのアクセスのため .env.local
ファイルを作成し認証情報を入力します。
CONTENTFUL_SPACE_ID=your_space_id
CONTENTFUL_PREVIEW_ACCESS_TOKEN=your_preview_api_token
CONTENTFUL_PREVIEW_SECRET=YOUR_PREVIEW_SECRET
Contentful クライアントの設定
Contentful とのやり取りを行う lib/contentful.js
を作成します。
import { createClient } from 'contentful'
/**
* Contentful Preview API 専用クライアントの作成
*
* Preview API を使用することで、下書き状態のコンテンツも取得可能
* 通常の Delivery API では公開済みコンテンツのみ取得できる
*/
export const previewClient = createClient({
space: process.env.CONTENTFUL_SPACE_ID, // Contentful スペース ID
accessToken: process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN, // Preview API 用のアクセストークン
host: 'preview.contentful.com', // Preview API のエンドポイント
})
Preview API エンドポイントの実装
Preview API エンドポイントとして app/api/preview/route.js
を作成します。
import { redirect } from 'next/navigation'
/**
* Contentful からのプレビューリクエストを処理する API エンドポイント
*
* Contentful の管理画面でプレビューボタンをクリックした際に呼び出される
* 認証後、該当するブログ記事ページにリダイレクトする
*/
export async function GET(request) {
// URL パラメータから secret と entry ID を取得
const { searchParams } = new URL(request.url)
const secret = searchParams.get('secret') // 認証用のシークレットキー
const id = searchParams.get('id') // プレビュー対象のエントリ ID
// 認証チェック: シークレットキーの検証とエントリ ID の存在確認
if (secret !== process.env.CONTENTFUL_PREVIEW_SECRET || !id) {
return new Response('Invalid token', { status: 401 })
}
// 認証成功時、該当するブログ記事ページにリダイレクト
redirect(`/blog/${id}`)
}
ブログ記事表示ページの実装
プレビュー機能の本体である app/blog/[id]/page.js
を作成します。
import { previewClient } from '../../../lib/contentful'
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'
/**
* ブログ記事のプレビューページコンポーネント
*
* Contentful の Preview API を使用して、下書きを含むすべてのエントリを表示
* Rich Text フィールドを適切にレンダリングする
*/
export default async function BlogPost({ params }) {
// Next.js 15 では params を await で取得する必要がある
const resolvedParams = await params
try {
// Preview API を使用してエントリを取得
// これにより下書き状態のコンテンツも取得可能
const entry = await previewClient.getEntry(resolvedParams.id)
return (
<div style={{ padding: '2rem', maxWidth: '800px', margin: '0 auto' }}>
{/* プレビューモードであることを示すバナー */}
<div style={{
background: '#f0f8ff',
padding: '1rem',
marginBottom: '2rem',
border: '1px solid #0066cc'
}}>
🔍 Preview Mode - Entry ID: {resolvedParams.id}
</div>
{/* 記事タイトルの表示 */}
<h1>{entry.fields.title || 'No Title'}</h1>
{/* Rich Text 本文の表示 */}
{entry.fields.body && (
<div>
{/*
* documentToReactComponents を使用して Rich Text をレンダリング
* Contentful の Rich Text 形式を React コンポーネントに変換
*/}
{documentToReactComponents(entry.fields.body)}
</div>
)}
{/* 本文が存在しない場合のフォールバック表示 */}
{!entry.fields.body && (
<p style={{ color: '#666', fontStyle: 'italic' }}>
本文が設定されていません
</p>
)}
</div>
)
} catch (error) {
// エラーハンドリング: エントリが見つからない場合やAPI エラーの処理
return (
<div style={{ padding: '2rem' }}>
<h1>記事が見つかりません</h1>
<p>Entry ID: {resolvedParams.id}</p>
<p>Error: {error.message}</p>
</div>
)
}
}
動作確認
開発サーバーの起動
下記のコマンドでローカルにサーバーを起動し、動作を確認します。
npm run dev
表示されている URL をブラウザで開き、 Next.js のテンプレート画面が表示されれば正常に起動が行われています。
プレビューの確認手順
Contentful コンソールの Content > Add entry から BlogPost を選択し、記事の内容を入力してから Open Live Preview を選択します。
プレビューが表示されることを確認します。
まとめ
本記事では、Next.js を使用した Contentful Content Preview の最小構成実装を紹介しました。この機能は、リアルタイムで出力結果を確認しながら編集を行いたいというユースケースにおいて非常に有効です。