web

Next.js × microCMSのブログにプレビュー機能をつける

公開日:2022年1月16日
最終更新日:2022年1月16日
目次

Next.jsとmicroCMSで作っているブログにプレビュー(下書き)機能をつけてみました。

仕組み

仕組みとしては以下です。

  • microCMSの管理画面からプレビューを開く
  • プレビュー関数が動く
  • PreviewDatadraftkey をセットし、プレビュー用のcookieが発行され、ブログ画面にリダイレクト
  • 画面に表示


プレビュー用関数

pages/api/preview/index.ts に以下を書きます。

import { NextApiRequest, NextApiResponse } from 'next'
import { client } from '@/libs/client'

const preview = async (req: NextApiRequest, res: NextApiResponse) => {
  const { draftKey, slug } = req.query

  if (typeof draftKey !== 'string' || typeof slug !== 'string') {
    res.status(404).end()
    return
  }

  const data = await client.get({
    endpoint: 'blog',
    contentId: slug,
    queries: {
      draftKey,
    },
  })

  if (!data) {
    return res.status(401).json({ message: 'Invalid slug' })
  }

  res.setPreviewData({ ...data, draftKey })
  res.writeHead(307, { Location: `/blog/${data.category.id}/${data.id}` })
  res.end('Preview mode enabled')
}

export default preview


ブログコンポーネントの修正

getStaticProps を修正します。必要な箇所だけ書き出してます。

export const getStaticProps: GetStaticProps<StaticProps> = async (context) => {
  const { params, previewData } = context
  if (!params?.category || !params?.id) {
    throw new Error('Error: ID not found')
  }

  const draftKey = isDraft(previewData)
    ? { draftKey: previewData.draftKey }
    : {}

  try {
    const id = toStringId(params.id)
    const data = await client.get({
      endpoint: 'blog',
      contentId: id,
      queries: {
        ...draftKey,
      },
    })

    return {
      props: {
        blog: data,
        ...draftKey,
      },
    }
  } catch (e) {
    return { notFound: true }
  }
}


プレビュー有効のテキストを表示

現在プレビュー中ですという文言を表示する

{draftKey && (
    <div>
      現在プレビューモードで閲覧中です。
      <Link href={`/api/exitPreview`}>
        <a>プレビューを解除</a>
      </Link>
    </div>
)}


プレビュー無効の関数

pages/api/exitpreview/index.ts にプレビューを止めるための関数を書きます。

import { NextApiRequest, NextApiResponse } from 'next'

const exitPreview = async (
  req: NextApiRequest,
  res: NextApiResponse
): Promise<void> => {
  res.clearPreviewData()
  res.writeHead(307, { Location: `/` })
  res.end('Preview mode disabled')
}

export default exitPreview


micorCMSの設定

管理画面の「API設定」→「画面プレビュー」にURLを設定します。

https://your-domain.com/api/preview?slug={CONTENT_ID}&draftKey={DRAFT_KEY}


プレビュー

これで準備できたので、記事を書いて下書き保存をし、プレビューボタンを押すと、公開前に見た目のチェックができます。

About the author

大阪でフロントエンドエンジニアをしています。写真を撮るのが趣味です。よかったら500pxに載せてる写真も見てください。
web上に公開しているので、正確さに可能な限り努力してますが、個人の備忘録程度に書いてるので、ご自身の判断で参考程度に読んでください。
間違いやご意見があれば、コンタクトやSNSに気軽にご連絡ください。

Read next

Category

  • web
  • 雑記