質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

[Nextjs] getStaticPaths() の paths に値が渡せない?

受付中

回答 0

投稿

  • 評価
  • クリップ 1
  • VIEW 54

score 37

いつも大変お世話になっております。

表題について質問です。

WordpressとNextの組み合わせでブログサイトを作成しています。
その中で現在ページネーション機能を作成しているのですが、
どうしてもエラーが発生してしまい、上手く改善することができません。

エラー箇所は pages/entry/page/[id].js の getStaticPaths() です。

ページネーションのURLは以下を形を想定しています。

http://localhost:3000/entry/page/1
http://localhost:3000/entry/page/2
http://localhost:3000/entry/page/3

paths に渡す値で何かしら問題が発生していると思いますが、
pages/entry/[id].js の getStaticPaths() では問題はなく、
pages/entry/page/[id].js のみでエラーが発生しています。

pages/entry/[id].js の getStaticPaths() で渡している値は、

[
  {params: {id: '3410'}},
  {params: {id: '3405'}},
  ...
]

pages/entry/page/[id].js の getStaticPaths() で渡している値は、

[
  {params: {id: '1'}},
  {params: {id: '2'}}
  ...
]

です。
比較してみると、id の数値が異なるのみで、それ以外は全く同じになります。
なぜこのような感じになってしまうのでしょうか、、?
どなたか詳しい方がいらっしゃればご教授いただけますと幸いです。

もし不足している情報等あればお気軽にお申し付けください。
それではどうぞ宜しくお願い致します。

エラー内容

Server Error
Error: Error serializing `.postsCount` returned from `getStaticProps` in "/entry/page/[id]".
Reason: `object` ("[object Promise]") cannot be serialized as JSON. Please only return JSON serializable data types.

ソースコード

ディレクトリ構造

# 利用しているファイルのみ記述しています。

.
├── components
│   ├── Layout.js
│   ├── Pagination.js
│   └── Post.js
├── lib
│   └── posts.js
└── pages
     ├── entry
     │   ├── [id].js
     │   └── page
     │       └── [id].js
     └── index.js

lib/posts.js

import axios from "axios";
import {PER_PAGE} from "../components/Pagination";


// 1ページあたりの取得ページ数
export const PER_PAGE_NUM = PER_PAGE;

// すべての記事取得
export const getAllPosts = async () => {
  const res = await axios.get(`${process.env.NEXT_PUBLIC_RESTAPI_URL}/custom/posts`);
  return res.data;
}

// 記事総数
export const getAllPostsCount = async () => {
  const res = await axios.get(`${process.env.NEXT_PUBLIC_RESTAPI_URL}/custom/posts_count`);
  return res.data;
}

// すべての記事ID取得
export const getAllPostIds = async () => {

  const res = await axios.get(`${process.env.NEXT_PUBLIC_RESTAPI_URL}/custom/posts`);

  // id を 配列(オブジェクト,オブジェクト,...) で格納
  return res.data.map((post) => {
    return {
      params: {
        id: String(post.id)
      }
    }
  });
}

// トップページの記事一覧を取得
export const getTopPagePosts = async (pageNum) => {
  const res = await axios.get(`${process.env.NEXT_PUBLIC_RESTAPI_URL}/posts?per_page=${pageNum}&page=1`);
  return res.data;
}

// 1つ記事取得
export const getPost = async (id) => {
  const res = await axios.get(`${process.env.NEXT_PUBLIC_RESTAPI_URL}/posts/${id}`);
  return res.data;
}

// ページネーション -  1ページあたりの記事を取得
// pageNum : 何ページ目か
export const getPostPerPagination = async (pageNum) => {
  const res = await axios.get(`${process.env.NEXT_PUBLIC_RESTAPI_URL}/posts?per_page=${PER_PAGE_NUM}&page=${pageNum}`);
  return res.data;
}

page/entry/page/[id].js

// lib
import {getAllPostsCount, getPostPerPagination} from "../../../lib/posts";

// components
import Layout from "../../../components/Layout";
import Post from "../../../components/Post";
import Pagination, {PER_PAGE, range} from "../../../components/Pagination";


export default function PaginationPerPage({posts, postsCount}) {
  return (
    <Layout>

      <ul>
        {posts && posts.map((post) => <Post key={post.id} post={post}/>)}
      </ul>

      <Pagination postsCount={postsCount}/>

    </Layout>
  )
}

export const getStaticPaths = async () => {

  const postsCount = await getAllPostsCount();
  const pageCount = range(1, Math.ceil(postsCount / PER_PAGE));

  const paths = pageCount.map((pageNum) => {
    return {
      params: {
        id: String(pageNum)
      }
    }
  })

  return {paths, fallback: false};
}

export const getStaticProps = async ({params}) => {

  const posts = await getPostPerPagination(params.id)
  const postsCount = getAllPostsCount();

  return {
    props     : {posts, postsCount},
    revalidate: 3,
  };
}

pages/entry/[id].js

import Link from "next/link";
import {useRouter} from "next/router";

// lib
import {getPost, getAllPostIds} from "../../lib/posts";

// components
import Layout from "../../components/Layout";


const Post = ({post}) => {

  const router = useRouter();

  if (router.isFallback || !post) {
    return <div>Loading...</div>
  }

  return (
    <Layout title={post.title.rendered}>

      <h1>{post.title.rendered}</h1>

      <article>{post.content.rendered}</article>

      <Link href="/">
        <a>記事一覧へ戻る</a>
      </Link>

    </Layout>
  )
}

export default Post;

export const getStaticPaths = async () => {

  const paths = await getAllPostIds();

  return {paths, fallback: true};
}


export const getStaticProps = async ({params}) => {

  const post = await getPost(params.id);

  return {
    props     : {post},
    revalidate: 3,
  };
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る