9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SuperJSONでNext.js 12以降のgetServerSidePropsやgetStaticPropsをスマートに書く

Last updated at Posted at 2022-03-18

Next.jsのgetServerSidePropsgetStaticPropsとJSON

Next.jsでSSRやSSRをする際に使うgetServerSidePropsgetStaticPropsでは、戻り値をJSONでシリアライズ可能な型に制限しなくてはならない制約があります。例えばデータベースから取得したデータがDate型を含む場合はエラーになってしまいます。

  • getStaticPropsでMongoDBデータベースから取得したデータがDate型の値を含む場合:
export const getStaticProps:GetStaticProps = async (ctx) => {
  const client = await new MongoClient("mongodb://127.0.0.1:27017");
  await client.connect();
  const db = client.db("DATABASE");
  const col = db.collection("COLLECTION");
  const posts = await col.find({}).toArray(); #created_atなどDate型を含んでいるとする 
  return {
    props:{
      posts
    }
  }
}

エラー

Server Error
Error: Error serializing `.data[0].date` returned from `getStaticProps` in "/".
Reason: `object` ("[object Date]") cannot be serialized as JSON. Please only return JSON serializable data types.
This error happened while generating the page. Any console logs will be displayed in the terminal window.
  • undefinedを含む場合:

コード

export const getStaticProps:GetStaticProps = async (ctx) => {
  return {
    props:{
      data: undefined
    }
  }
}

エラー

Server Error
Error: Error serializing `.data` returned from `getStaticProps` in "/".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
This error happened while generating the page. Any console logs will be displayed in the terminal window.

これを回避するためには、Date型をString型に変換するなど、JSONとしてシリアライズ可能な形式に変換する必要がありますが、毎回変換処理を書くのは面倒です。

こんなときに便利なライブラリがSuperJSONです。SuperJSONとNext.js用のBabelプラグインを使えば明示的な変換なしにgetServerSidePropsgetStaticPropsでJSON範囲外のDate型などが扱えます。

Next.js 12以降でのSuperJSON

しかしながらNext.js 12では標準のトランスパイラがBabelからSWCに変更され、blitz-js/babel-plugin-superjson-nextが標準では使えなくなりました。

SWC以降のNext.jsでもこれまでと同じようにSuperJSONを使えるようにしたのが、2021年12月に登場したremorses/next-superjsonです。

インストール

npm install superjson (未インストールの人)
npm install next-superjson

設定

next.config.jsnext-superjson用の設定を追加します。

const { withSuperjson } = require('next-superjson')

module.exports = withSuperjson()({
  reactStrictMode: true,
})

アプリ側の処理

特に何も記述する必要はありません。SuperJSONを使わない場合はシリアライズが必要ですが自動でシリアライズしてくれます。

注意

  • SuperJSONがSWC対応してくれるのが望ましいですが、未対応のためワークアラウンドとして使っています。将来SuperJSONがSWCに対応したらそちらに移行しましょう。
  • 楽だからといってデータベースから取得したデータをNext.jsにそのまま投げるのはやめましょう。
9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?