JavaScriptmicroCMSNext.jsReactSaaS / FaaS

Next.js App RouterでmicroCMSの画面プレビューに対応する

microCMSのテンプレート作成に挑戦する中で、画面プレビューの実装を行いました。Next.js App Routerを使用してmicroCMSのプレビュー機能を実装する方法を紹介します。ngrokを使用してローカルのNext.jsアプリに中継するためのセットアップ方法も紹介されています。microCMSのAPI設定画面でngrokのURLを設定し、Next.js側では公開済みのコンテンツを表示するページを用意する必要があります。また、プレビューコンテンツの取得にはdraft_keyを利用します。

広告ここから
広告ここまで

microCMSのテンプレート作成に挑戦する中で、画面プレビューをはじめて実装しました。

今回はNext.js App RouterでmicroCMSのプレビュー機能を実装する方法を簡単に紹介します。

ngrokでローカルのNext.jsにプロキシーする

Next.jsアプリのセットアップ方法については割愛します。

ローカルでこの機能を開発するには、microCMSから送信されるWebhookイベントを、ローカルのNext.jsアプリに中継する必要があります。

今回はngrokを利用して、リクエストを中継します。

npm run dev
ngrok http 3000

URLが発行されましたので、コピーしましょう。

Session Status                online                                                        
Account                       John due (Plan: Free)                                 
Update                        update complete, restart for new version!                     
Version                       3.1.0                                                         
Region                        Japan (jp)                                                    
Latency                       25ms                                                          
Web Interface                 http://127.0.0.1:4040                                         
Forwarding                    https://xxxx-xxxx-xxxx-xxxx.ngrok-free.app -> http://localhost:3000
                                           

microCMSで、ngrokのURLを設定する

ngrokで発行されたURLを、microCMSのプレビューURLに設定しましょう。

[API設定画面]の[画面プレビュー]を開き、[遷移先URL]にURLを入れます。

/app/products/[content_id]/page.tsxに遷移させたい場合、https://xxx-xxx-xxx-xxx.ngrok-free.app/products/{CONTENT_ID}?draft_key={DRAFT_KEY}のように設定します。

[画面プレビューボタンの表示]をオンにして保存しましょう。

App Routerで公開済みのコンテンツを表示するページを用意

続いてNext.js側にページを用意します。まずはmicroCMSのJS SDKセットアップと、記事取得処理のラッパー関数を用意します。

import { createClient } from 'microcms-js-sdk'
import type { MicroCMSListContent, MicroCMSQueries } from 'microcms-js-sdk'

if (!process.env.MICROCMS_SERVICE_DOMAIN) {
  throw new Error('MICROCMS_SERVICE_DOMAIN is required')
}

if (!process.env.MICROCMS_API_KEY) {
  throw new Error('MICROCMS_API_KEY is required')
}
export const client = createClient({
  serviceDomain: process.env.MICROCMS_SERVICE_DOMAIN,
  apiKey: process.env.MICROCMS_API_KEY,
})

export const getProductById = async (id: string, queries: MicroCMSQueries = {}) => {
  return client.get<MicroCMSListContent>({
    endpoint: 'products',
    contentId: id,
    queries,
  })
}

続いてページを用意しましょう。

app/product/[content_id]/page.tsxを、次のように実装します。

import { getProductById } from '@/app/libs/microcms'
import { notFound } from 'next/navigation'

type PageProps = {
  params: {
    id: string
  }
}

export default async function Product({ params: { id: productId } }: PageProps) {
  const product = await getProductById(productId).catch(() => null)
  if (!product) {
    notFound()
  }
  return <pre><code>{JSON.stringify(product, null, 2)}</code></pre>
}

今回は、あくまでデータ取得だけにフォーカスするため、JSONデータをそのまま出力させます。

App RouterでmicroCMSのプレビューコンテンツを取得できるようにする

先ほどのコードは、まだ画面プレビューに対応していません。

次のコードに変更して、microCMSから送信されるdraft_keyを利用したプレビュー記事の取得に対応しましょう。

import { getProductById } from '@/app/libs/microcms'
import { notFound } from 'next/navigation'

type PageProps = {
  params: {
    id: string
  }
  searchParams: {
    draft_key?: string
  }
}

export default async function Product({ params: { id: productId }, searchParams }: PageProps) {
  let product = await getProductById(productId).catch(() => null)
  if (!product) {
    const draftKey = searchParams?.draft_key || null
    if (draftKey) {
      product = await getProductById(productId, {
        draftKey
      }).catch(() => null)
    }
  }
  if (!product) {
    notFound()
  }
  return <pre><code>{JSON.stringify(product, null, 2)}</code></pre>
}

「公開ずみのページ」と「下書きプレビュー」を同じファイルで処理するため、すこし乱暴ですが、APIを2回叩く実装にしています。

公開記事として取得できなかった場合は、下書きを取得するイメージですね。

もしかすると、draft_keyの有無で呼び出し方を変えても良いかもしれません。

動作確認

準備ができたので、実際にアクセスしてみましょう。

新しく記事を作ると、[画面プレビュー]ボタンが表示されます。これをクリックしましょう。

エラーにならず、記事内容が表示されました。

デプロイ後にURLを変更しよう

ngrokのままではいろいろ不便なので、デプロイ後は切り替えておきましょう。

もしより安全に運用したい場合は、searchParams.draft_keyがある場合は認証を通すmiddlewareとかを用意するとよいかもしれません。

関連記事

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts