NextとmicroCMSでの「前の記事」「次の記事」の実装方法
目次
microCMSでは現在直接「前の記事」「次の記事」」を再現するような、apiは提供されていないようです。
ただ工夫することで解決できるので、自分がやった方法を書いておきます
参考になればと思います。
一つ前 / 一つ後ろのコンテンツはどのように取得すれば良いですか?
こちらの公式の記事をを参考にしようと思ったのですがqueries: {limit: 1000, fields: 'id,title'}
として1000件と指定して全て取ってくるようにするという方法が書かれています。
あまり全件取得ということはしたくないので別の方法をやってみました。
前提
実装時の考え方
- 現在の記事を取得する
- 現在の公開日より前、後の記事を1件だけフィルターを使って取得
こうすることで必要な1件のみを取得することができます。
client.ts
import { createClient } from 'microcms-js-sdk';
export const client = createClient({
serviceDomain: process.env.API_NAME || '',
apiKey: process.env.API_KEY || '',
})
microCMSで登録してある、「名前」と「API_KEY」を入れてあげます。
記事部分のts「getStaticProps部分」
import { client } from '~/utils/client'
import { GetStaticProps } from 'next'
export const getStaticProps: GetStaticProps<Home, Params> = async (context) => {
const id = context.params?.id
const entry = await client.get<Entry>({ endpoint: 'entries', contentId: id})
const fields = 'id,title,image,publishedAt'
const prev = await client.get<EntriesApi>({
endpoint: 'entries',
queries: {
limit: 1,
orders: '-publishedAt',
fields,
filters: `publishedAt[less_than]${entry.publishedAt}`
}
})
const next = await client.get<EntriesApi>({
endpoint: 'entries',
queries: {
limit: 1,
orders: 'publishedAt',
fields,
filters: `publishedAt[greater_than]${entry.publishedAt}`
}
})
const prevEntry = prev.contents[0] || {}
const nextEntry = next.contents[0] || {}
return {
props: {
entry,
prevEntry,
nextEntry
},
}
}
getStaticProps
であらかじめ「前の記事」「次の記事」を取得してpropsで渡してあげるようにしています。
fieldsで使いたい部分のみ取得
const fields = 'id,title,image,publishedAt'
を指定することで必要な情報だけに絞ることができます。 こうしておくことで、api取得時にメインの記事の情報を含めないので、apiレスポンスが少し軽くなります。
記事apiレスポンスの型定義
export interface Entry {
title: string
description?: string
id?: string
publishedAt?: string
updatedAt?:string
body?: Body[]
image?: ImageInfo
thumbnail?: ImageInfo
categories?: Category[]
tags?: Tag[]
}
export interface EntriesApi extends ListApi {
contents: Entry[]
}
自分で設定したfield
に合わせて型を用意します。
「前の記事」の実装
const prev = await client.get<EntriesApi>({
endpoint: 'entries',
queries: {
limit: 1,
orders: '-publishedAt',
fields,
filters: `publishedAt[less_than]${entry.publishedAt}`
}
})
<EntriesApi>
の部分でapiで返ってくる型を定義しています。limit
1件のみ必要なので絞っています。-publishedAt
最新が欲しいので、公開日(publishedAt)で降順に。filters:
publishedAt[less_than]${entry.publishedAt}
でフィルターをかける。この部分が重要になってきます。
「公開日:publishedAt
」を「記事の公開日: entry.publishedAt
」「より前: [less_than]
」で取得というふうにフィルターをかけています。
「次の記事」の実装
const next = await client.get<EntriesApi>({
endpoint: 'entries',
queries: {
limit: 1,
orders: 'publishedAt',
fields,
filters: `publishedAt[greater_than]${entry.publishedAt}`
}
})
「前の記事」と考え方は一緒です。差分としては
[greater_than]
のフィルター部分を[greater_than]
に変更します。
「公開日:publishedAt
」を「記事の公開日: entry.publishedAt
」「より後: [less_than]
」で取得というふうに変更してあげます。
まとめ
今回は「前の記事」「次の記事」に必要な部分だけを抜き出して説明しました。
microCMSで用意してくださっているsdkは、filter
やorders
など細かく設定できるようになっているので、工夫次第で色々できてよいですね。
公式で直接目的のapiが用意されていた場合はそちらを使えばいいのですが。 全部が用意されてるわけではないので、工夫しつつ再現できると良いですね。
今後もmicroCMSは色々と更新していってるようなので、いろいろなものが簡単に作るれるようになることに期待です!