3@TECH BLOG

日々の業務で得た知見やノウハウ、技術情報などを発信します。

Next.js × microCMSのSSGサイトでプレビュー画面を実装する

2025-08-19 microCMS

microCMS では管理画面からプレビュー用URLを設定し、公開前の記事を実際の見た目で確認できます。
しかし、Next.js + microCMS でプレビュー画面を実装する際、SSG(静的書き出し)設定をしているとビルドが通らないという壁にぶつかりました。

プレビュー画面について

microCMS では、下書き記事でも「プレビュー」表示が可能です。
プレビューを表示するには、まずAPI設定の「遷移先URL」に次のようなURLを設定します。
https://yourdomain.com/blog/preview/{CONTENT_ID}?dk={DRAFT_KEY}

  • {DRAFT_KEY} 下書き用のドラフトキー(draftKey)
  • {CONTENT_ID} 記事のコンテンツID

この2つを受け取って表示するページをNext.js側に用意すれば、下書きプレビューが実現します。
 

課題

今回のサイトは全体をSSGで構築するため、Next.js の next.config.js に次のように設定していました。
 

next.config.js
output: 'export'

これはすべてのページを静的に書き出すための設定です。
しかし、この設定を有効にした状態で「app/blog/preview/[slug]/page.tsx」のような動的ルートで「draftKey」を使ってデータ取得をしようとするとビルドエラーになりました。
Error: Page "/blog/preview/[slug]" is missing "generateStaticParams()" so it cannot be used with "output: export" config.

  • 「output: 'export'」では、すべてのページがビルド時に静的に生成される必要がある
  • いっぽうプレビューは「draftKey」を使って実行時に取得したい(= 静的生成できない)

そのため、ビルドが失敗してしまいました。

動的ルートをやめ、クライアントで取得して解決

これを回避するため、まずルーティングを「/blog/preview」に固定し、「記事ID」や「draftKey」はクエリパラメータ(?slug={CONTENT_ID}&dk={DRAFT_KEY})で受け取る形に変更しました。
https://yourdomain.com/blog/preview?slug={CONTENT_ID}&dk={DRAFT_KEY}

そして、ビルド時ではなくブラウザ側でデータを取得できるように、処理をクライアントコンポーネント(Client.tsx)に移しました。
こうすると「/blog/preview」は静的に1ページとして出力され、表示時にクエリを読んでmicroCMSからデータを取ってきます。
これでSSGのサイトでもプレビュー画面を実装することができました。
 

page.tsx
import Client from './Client';
import { Suspense } from 'react';

export default async function Page() {
  return (
    <>
      <suspense>
        {/* @ts-expect-error Server Component */}
        <client>
      </client></suspense>
    
  );
}
Client.tsx
"use client";

import { getBlogDetail } from '@/app/_libs/microcms';
import { useSearchParams } from 'next/navigation'

export default async function Client() {
  const searchParams = useSearchParams();
  const dk = searchParams.get('dk') || '';
  const slug = searchParams.get('slug') || '';

  const data = await getBlogDetail(slug, {
    draftKey: dk,
  });

  return (
    <>
      // ここにプレビュー画面の内容を記述
    
  );
}

Contact お問い合わせ

お気軽にお問い合わせください。

PageTop