🐕

Next.js で不用意に日付を扱うとエラーになるよ

2024/03/11に公開

自分は Next.js を使って Jamstack サイト制作や WEB アプリ開発をしています。やっぱりいつでもエラーとの戦いなので同じように今困っている方の少しでも役に立てれば良いなと思います。

こんなエラー起きていませんか?

ローカルで開発している時は全く問題なかったのにホスティングをしてコンソールをみると下記のようなエラーがめちゃくちゃ出てる!!!!!!!っていう経験ないですか?

Error: Minified React error #425; visit https://reactjs.org/docs/error-decoder.html?invariant=425 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

さらに困ったことに minify されてしまっているのでホスティングされた状態からエラーを特定することができないんですよね。ただこれ知っていればすぐに解決することができます!!

実は日付を扱っているところで起こります。コーポレートサイトとかだと news 系の投稿日時などでよく日付使いますよね。大体これが原因です。
またローカルでもこのエラーを出すように設定する方法もご紹介します。

エラーの解消方法

dayjs などの日付系ライブラリを使って

import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";

dayjs.extend(utc);
dayjs.extend(timezone);

export const formatCommon =
  (format: string) =>
  (date: string | Date | number): string => {
    return dayjs.utc(date).tz("Asia/Tokyo").format(format) as string;
  };

export const formatDate = formatCommon("YYYY年MM月DD日 hh:mm");

こんな感じで JST で表記するようにすれば解決します。

https://day.js.org/

そもそもエラーの起こる理由とは

簡単に説明をすると

例えば Jamstack で制作されたサイトだとすると、ヘッドレス CMS 使いますよね?例えば microCMS とか。

news の投稿日時などの日付データは ISO 8601 形式の UTC(協定世界時)にて返却されます。
フロント側で JST にする必要があるんですが、そうするとサーバーとフロントで表示される日付が変わってしまいますよね。それでエラーがおきます。

なので実際にはこんなエラーが出ています

app-index.js:35 Warning: Text content did not match. Server: "2024年03月04日 03:00" Client: "2024年03月05日 12:00"

実験してみる

仮に microCMS で日付入力をこのような形で作ったとして

image

microCMS で日付入力で 2024/3/9 を選択したとして API のレスポンスでは 2024-03-09T15:00:00.000Z’と返されます。

そのレスポンスを Next.js でを表示させると

image

server では 2024 年 03 月 08 日 03:00
client では 2024 年 03 月 09 日 12:00

表示されるものが違うので React の方で怒っています。
ローカル環境ではタイムゾーンが JST なのに、本番環境(Vercel など)では、タイムゾーンが UTC なのでこうゆうことが起こります。

ローカル環境でわかれば

開発環境で引き起こすことができれば本番にホスティングした後に気づくこともなくなりますよね。
package.json の scripts に以下を記述することでローカル環境でも引き起こすことができます。

"scripts": {
- "dev": "next dev",
+ "dev": "TZ='Etc/UTC' next dev",
  "build": "next build",
  "start": "next start",
},

実際にブラウザを確認すると下記のようにエラーが出ています。これでデバッグしやすいですね。

app-index.js:35 Warning: Text content did not match. Server: "2024年03月04日 03:00" Client: "2024年03月05日 12:00"

Discussion