Next.jsのエラーの原因を調べた話 Reason: `undefined` cannot be serialized as JSON.
ことの発端
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 より取得したブログ記事のデータをコンポーネントに渡したかったのですが、description
とthumbnail2は
はブログ記事に必須でないフィールドとしていたため、undefied
をきっちり付けていました。Typescript 的には特に問題はありません。
getStaticProps の戻り値は JSON 形式でコンポーネントに渡されるという Next.js の仕様があり、Javascript の JSON パーサーの仕様ではundefined
は有効な値でないとのことでした。
該当箇所を抜粋すると、
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