🐙

Next.jsのエラーの原因を調べた話 Reason: `undefined` cannot be serialized as JSON.

2022/08/20に公開

ことの発端

Next.js の getStaticProps 関数で処理を実装中に、次のエラーに遭遇しました。

Error: Error serializing `.contentMetaDatas[0].thumbnail2` returned from `getStaticProps` in "/blogs/[...slug]".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.

原因

結論から言うと、getStaticProps 関数の戻り値 props のオブジェクトにundefinedを代入していたことが原因でした。

次のようなコードを記述していました。

export const getStaticProps: GetStaticProps<Props, Params> = async (context) => {

    // ヘッドレスCMSより取得したデータがcontentに格納される
    // ...中略

    return {
      id: content.id,
      publishedAt: content.publishedAt,
      revisedAt: content.revisedAt,
      contentType: content.contentType[0],
      title: content.title,
      description: "description" in content ? content.description : undefined,
      tags: content.tags,
      thumbnail: content.thumbnail.url,
      thumbnail2: "thumbnail2" in content ? content.thumbnail2!.url : undefined,
    };
};

ヘッドレス CMS より取得したブログ記事のデータをコンポーネントに渡したかったのですが、descriptionthumbnail2ははブログ記事に必須でないフィールドとしていたため、undefied をきっちり付けていました。Typescript 的には特に問題はありません。

getStaticProps の戻り値は JSON 形式でコンポーネントに渡されるという Next.js の仕様があり、Javascript の JSON パーサーの仕様ではundefinedは有効な値でないとのことでした。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

該当箇所を抜粋すると、

undefined、 関数 (Function)、シンボル (Symbol) は有効な JSON 値ではありません。変換中にそのような値に遭遇した場合は、 (オブジェクトの中で発見された場合は) 省略されたり、 (配列の中で見つかった場合は) null に変換されたりします。 JSON.stringify は JSON.stringify(function(){}) や JSON.stringify(undefined) のように「純粋」な値を渡した場合に undefined を返すことがあります。

つまり、JSON でundefiedが代入されていると変な挙動をするから代入しないでね、と警告してくれたエラーでした。

解決方法

undefined ではなく空文字列を代入するように変更して解決しました。(Null でも良いです)

export const getStaticProps: GetStaticProps<Props, Params> = async (context) => {

    // ヘッドレスCMSより取得したデータがcontentに格納される
    // ...中略

    return {
      id: content.id,
      publishedAt: content.publishedAt.split("T")[0],
      revisedAt: content.revisedAt.split("T")[0],
      contentType: content.contentType[0],
      title: content.title,
      description: "description" in content ? content.description : "",
      tags: content.tags,
      thumbnail: content.thumbnail.url,
      thumbnail2: "thumbnail2" in content ? content.thumbnail2!.url : "",
    };
};

Next.jsというよりはJavascriptのJSONの扱いによるエラーでした。
初歩的な問題とは思いますが、1つ勉強になりました。

Discussion