NextでカテゴリなどgetStaticPropsを使って共通で定義したいけどできなかったので、別の方法での解決策
2021年10月4日
2022年1月10日
目次
pages
でカテゴリやタグをgetStaticProps
で定義していたのですが、
ページごとにjsonが吐き出されてしまって、共通にしたい内容なのにページごとのjsonに同じ内容が含まれてしまっていました。_app.tsx
でgetStaticProps
を使って共通化すれば良いかなと思ったのですが、pages
内でしか使えないようでした。
なので一工夫して解決してみました。
考え方
- Nodeであらかじめ、microCMSの必要なデータを取得してjsonで吐き出しておく。
- 使いたいところでjsonをimportして使う
実際のコード getMicroCMSdataについて
必要なもの
const fs = require('fs')
const axios = require('axios').default
const getMicroCMSdata = async (name, limit, query) => {
const url = `https://${process.env.API_NAME}.microcms.io/api/v1/${name}`
const apiKeyHeaderOption = { headers : { 'X-API-KEY': process.env.API_KEY }}
const getUrlOption = (number, url) => {
return url + `?limit=${number}${query}`
}
const getTotalCountUrl = getUrlOption(0, url)
const totalCountUrlData = await axios.get(getTotalCountUrl, apiKeyHeaderOption).then(r => r.data)
const { totalCount } = await totalCountUrlData
const getContentUrl = getUrlOption(limit || totalCount, url)
const contentUrlData = await axios.get(getContentUrl, apiKeyHeaderOption).then(r => r.data)
const data = await contentUrlData
return data
}
const generateIdsQuery = (ids) => {
return `&ids=${ids.join(',')}`
}
const createJSONdata = async() => {
const categories = await getMicroCMSdata('categories')
const tags = await getMicroCMSdata('tags')
const recentEntries = await getMicroCMSdata('entries', 5, '&orders=-publishedAt&fields=id,title,categories,tags,publishedAt,image,description')
const recommendEntries = await getMicroCMSdata('entries', 5, `&ids=${generateIdsQuery(['imagealpha_imageoptim_jpegmini','photoshop_full_bloom','menta'])}&orders=-publishedAt&fields=id,title,categories,tags,publishedAt,image,description`)
try {
fs.writeFileSync('const/microcms.json', JSON.stringify({ categories, tags, recentEntries, recommendEntries }))
console.log('create json!')
} catch (e) {
console.error(e);
}
}
createJSONdata()
package.jsonの記述
build時にyarn generateCmsData
を合わせて実行するようにしています。
(実行時はAPI_NAME=microCMSのKEY
API_KEY=microCMSのKEY
を指定する必要あり)
"scripts": {
"build": "yarn generateCmsData && yarn next build",
"generateCmsData": "node ./utils/serverGenerateCmsData"
},
実行方法
下記のような感じurils
にserverGenerateCmsData
をいれてNAME,KEYを入れて実行します。
API_NAME=microCMSのKEY API_KEY=microCMSのKEY yarn generateCmsData
getMicroCMSdataの引数
材料 | 量 |
---|---|
name | api名 |
limit | 取得したい件数(指定しない場合は全件) |
query | フィルターや降順、昇順などの指定 |
コードの説明
まず件数を0件で取得して、何件登録されているかのtotalCountを取得しています。
const getTotalCountUrl = getUrlOption(0, url)
const totalCountUrlData = await axios.get(getTotalCountUrl, apiKeyHeaderOption).then(r => r.data)
const { totalCount } = await totalCountUrlData
limitがある場合はlimitの数分、存在しない場合は上でとってきたtotalCount分のデータを取得します
const getContentUrl = getUrlOption(limit || totalCount, url)
const contentUrlData = await axios.get(getContentUrl, apiKeyHeaderOption).then(r => r.data)
const data = await contentUrlData
api名 categoriesの全権を取得しています
const categories = await getMicroCMSdata('categories')
api名 tagsの全権を取得しています
const tags = await getMicroCMSdata('tags')
最新のentriesを5件、必要なfieldsを公開日順に取得しています
const recentEntries = await getMicroCMSdata('entries', 5, '&orders=-publishedAt&fields=id,title,categories,tags,publishedAt,image,description')
idsを使って自分で選んだ記事を取得しています
const generateIdsQuery = (ids) => {
return `&ids=${ids.join(',')}`
}
const recommendEntries = await getMicroCMSdata('entries', 5, `&ids=${generateIdsQuery(['imagealpha_imageoptim_jpegmini','photoshop_full_bloom','menta'])}&orders=-publishedAt&fields=id,title,categories,tags,publishedAt,image,description`)
const/microcms.jsonにそれぞれ取得したjsonを文字列にして書き込んで吐き出すようにしました
fs.writeFileSync('const/microcms.json', JSON.stringify({ categories, tags, recentEntries, recommendEntries }))
吐き出したコードをを使う
実際に吐き出したjsonを使う場合はimport
して使っています。
import cmsData from '~/const/microcms.json'
console.log(cmsData.categories.contents)
まとめ
下記参考にさせていただきました。
Nextデフォルトの機能で、共通で使えるgetStaticProps
的なのがあればよいんですけどね。。
Nextも日々進化してるので、新しい機能でてきたら書き直したいですね。