この記事の目的
- MicroCMSのプレビュー機能が出来るようになること。
- プレビュー機能作成でつまづいたのでメモ
前提
- 既にnetlifyに対してデプロイを行なっている
- microCMSとnext.jsの連携も行なっている
- 基本的なページは完成している(react等で実装が終わっている)
環境
package.json
{
"name": "myProject",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"microcms-js-sdk": "^2.0.0",
"next": "12.1.5",
"react": "18.0.0",
"react-dom": "18.0.0"
},
"devDependencies": {
"@types/node": "17.0.26",
"@types/react": "18.0.6",
"@types/react-dom": "18.0.2",
"eslint": "8.14.0",
"eslint-config-next": "12.1.5",
"typescript": "4.6.3"
}
}
1. targetをserverlessにする
参考: https://www.netlify.com/blog/2020/10/27/preview-mode-for-next.js-now-fully-supported-on-netlify/
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// ...
target: 'serverless',
// ...
}
module.exports = nextConfig
2. preview用のfunction実装
参考: https://nextjs-ja-translation-docs.vercel.app/docs/advanced-features/preview-mode
src/pages/api/preview.ts
export default function handler(req: any, res: any) {
// 後々に記述するが、これらのqueryの名前は自分で決める。contentTypeが今回はページのpathになっている
// pathが /articles/articleId の構成のサイトなら、 contentType = articles, contentId = articleId となる
const contentType = req.query?.contentType
const contentId = req.query?.contentId
// draftKeyは下書き用のkey。後々出てくる
const draftKey = req.query?.draftkey
if (!contentType || !contentId || !draftKey) {
return res.status(401).json({ message: 'Invalid params' })
}
res.setPreviewData({
contentId,
draftKey,
})
// ここは、ページ設計によるが、next+netlifyで作っていれば大体こうなるはず。
res.writeHead(302, {
Location: `/${contentType}/${contentId}`,
})
return res.status(200).json({ message: 'success' })
}
3. page側実装
src/pages/articles/[id].tsx
import { MicroCMSQueries } from 'microcms-js-sdk'
import { Article, getArticle } from '../../apis/microCms'
type Props = {
res: Article
}
type Params = {
id: string
}
type _PreviewData = {
contentId: string
draftKey: string
}
const ArticleDiv: NextPage<Props> = ({ res }) => {
// この辺は本件とは関係ないので省略
return (<div></div>)
}
export const getStaticPaths: GetStaticPaths<Params> = async () => {
const queries: MicroCMSQueries = { fields: 'id', limit: 100 }
const res = await getArticles(queries)
return {
paths: res.contents.map((article) => ({ params: { id: article.id } })),
fallback: false,
}
}
// contextに、preview.tsで取得したcontentIdとdraftKeyが格納されている
export const getStaticProps: GetStaticProps<Props, Params> = async (context) => {
const previewData = context.previewData as _PreviewData
const draftKey =
String(context.params!.id) === String(previewData?.contentId) ? previewData?.draftKey : ''
const res = await getArticle(context.params!.id, draftKey)
return {
props: {
res,
},
}
}
export default ArticleDiv
src/apis/microCms.ts
import { MicroCMSQueries } from 'microcms-js-sdk'
import { GetListDetailRequest, GetListRequest, MicroCMSListResponse } from 'microcms-js-sdk'
export type Article = {
id: string
title: string
}
export async function getArticles(queries?: MicroCMSQueries): Promise<MicroCMSListResponse<Article>> {
const getListRequest: GetListRequest = {
endpoint: 'articles',
}
if (queries) {
getListRequest.queries = queries
}
const res = await cmsClient.getList(getListRequest)
return res
}
export async function getArticle(id: string, draftKey?: string): Promise<Article> {
const detailQueries: GetListDetailRequest = { endpoint: 'articles', contentId: id }
if (draftKey) {
detailQueries.queries = { draftKey }
}
const res = await cmsClient.getListDetail(detailQueries)
return res
}
ここまで終わったら、netlifyにデプロイする
4. microCMSで設定
API設定画面より、
microCMSに従って、myprojectやcontentType部分を自分のプロジェクトに置き換えれば完了
5. プレビュー実行
記事ページが下書き状態で、画面プレビューボタンを押せば画面が見られる
おわりに
next.config.js 部分はもう少し知見が欲しいので、詳しい方いたらコメントお願いします