sugiii8's tech blog.
post: 2023-01-05
update: 2023-01-06
INDEX

Next.jsのブログにページングをつけてみた

thumbnail

自分のブログにページングついてないということに気づいていたが、良くも悪くもコンテンツがまだページングするほどではないためスルーしていました。
いい加減つけておこうと思い立ち対応しました。

microCMSのガイドがあったのでそれに沿って対応しました。
https://blog.microcms.io/next-pagination/

流れとしては上記記事の通りです

  • ページングコンポーネントを作成する
  • ブログ一覧ページにページングコンポーネントを導入する
  • ページング個別ページを作成する


ページングコンポーネントを作成する

記事に掲載されたコードをベースに下記を追加で対応しました

  • tsx化
  • tailwindでスタイリング
  • 1ページごとのコンテンツ数を定義
import Link from "next/link"

type PagenationProps = {
  totalCount: number
}
export const Pagination = (props: PagenationProps) => {
  const totalCount = props.totalCount


  const range = (start: number, end: number) =>
    [...Array(end - start + 1)].map((_, i) => start + i)


  return (
    <nav aria-label="Page navigation example">
      <ul className="inline-flex items-center -space-x-px">
        {range(1, Math.ceil(totalCount / PER_PAGE)).map((number, index) => (
          <li key={index}>
            <Link href={`/blogs/page/${number}`}>
              <a className="px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
                {number}
              </a>
            </Link>
          </li>
        ))}
      </ul>
    </nav>
  )
}

// TODO: 本来はもうちょっと数を増やすべきだが、ページングのテストのため5件にしている
export const PER_PAGE = 5


ブログ一覧ページにページングコンポーネントを導入する

  • getStaticPropsのパラメータにtotalCount(コンテンツ件数)を追加
type StaticProps = {
  blogList: BlogListResponse
  totalCount: number  // 追加
}
export const getStaticProps: GetStaticProps<StaticProps> = async () => {
  // 省略
   const totalCount = blogList.totalCount
  // 省略

  return {
    props: { blogList, totalCount },
  }

  // 省略
  • ページングコンポーネントを追加
<Pagination totalCount={totalCount} />


ページング個別ページを作成する

  • src/pages/blogs/page/[id].tsx を作成する
  • getStaticPaths でページのパスを定義する
export const getStaticPaths = async () => {
  const repos = await client.get({ endpoint: "blogs" })

  const pageNumbers = []

  const range = (start: number, end: number) =>
    [...Array(end - start + 1)].map((_, i) => start + i)

  const paths = range(1, Math.ceil(repos.totalCount / PER_PAGE)).map(
    (repo) => `/blogs/page/${repo}`
  )

  return { paths, fallback: false }
}
  • getStaticProps でページング個別ページのパラメータを定義する
export const getStaticProps: GetStaticProps<StaticProps> = async (context) => {
  const { params } = context

  if (!params?.id) {
    throw new Error("Error: ID not found")
  }
  const id = Number(params.id)

  const data = await client.get({
    endpoint: "blogs",
    queries: { offset: (id - 1) * 5, limit: 5 },
  })

  return {
    props: {
      blogs: data,
      totalCount: data.totalCount,
    },
  }
}


完成

以上!