Top View


Author Masayuki Yamaji

Nextjsを久々に使ったので備忘録

2024/02/29

案件で使用した構成

  • Amplify
    • Version 6.0.6
  • Nextjs
    • Version 14.0.3
    • app router

Nextjsの躓きポイント

Nextjsは以前から業務で何度か使用していたのですが、全てPages routerでした。

App routerを案件で使用したのは今回が初めてです。 公式のドキュメントチュートリアルがかなり充実しているのであまり苦しむことなく開発を進められたかと思います。

そんな中でも、躓いたのが以下3つです。

  • prefetchは開発環境ではオフ
  • server actionの例外の詳細は本番環境では隠しちゃうよ
  • postでもcacheしちゃうよ

prefetchは開発環境ではオフ

こちらもドキュメントに明記されているのですが、

Prefetching is not enabled in development, only in production.

開発モードだと、Linkコンポーネントを使用していてもprefetchされません。認証の有無で画面遷移が異なるページなど未認証時にページがprefetchされてしまい、認証後にも正しく画面が表示されないことが有りました。 ただ、開発モードでは再現しない為に、原因の特定に無駄に時間がかかりました。

server actionの例外の詳細は本番環境では隠しちゃうよ

こちらもドキュメントの通りなのですが、server action/server componentのスローされっぱなしのエラーオブジェクトのメッセージは開発モードでは問題なく表示されますが、本番モードでは機密漏洩を防ぐためにメッセージは表示されません。

以下のようなコードを書いた場合、本番・開発モードで挙動が異なります。

クライアント側

"use client";
import { hello } from "@/app/action";

export default function Home() {
  return (
    <>
      <button
        onClick={async () => {
          try {
            await hello();
          } catch (e) {
            console.log(e)
          }
        }}
      >
        click
      </button>
    </>
  );
}

サーバー側

"use server";
export async function hello() {
  throw new Error("サーバーで起こったエラーメッセージ");
}

開発モードでは、コンソールに サーバーで起こったエラーメッセージ と表示されますが、本番モードでは、

Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error

と表示されます。

この場合は、例外を投げっぱなしにするのではなく、サーバー側で補足して適切にクライアントに返す必要があるようです。

クライアント側

"use client";
import { hello } from "@/app/action";

export default function Home() {
  return (
    <>
      <button
        onClick={async () => {
          const message = await hello();
          console.log(message);
        }}
      >
        click
      </button>
    </>
  );
}

サーバー側

"use server";
export async function hello() {
  try {
    throw new Error("サーバーで起こったエラーメッセージ");
  } catch (e) {
    return e.message;
  }
}

(当たり前ですが、雑な処理を書く機密漏洩に繋がりますのでお気をつけください)

postでもcacheしちゃうよ

こちらもドキュメントに記載があるのですが、POSTリクエストでもcacheされます。(Route HandlerのPOSTメソットでない場合は)

cacheさせない方法もドキュメントに丁寧に記載があるので、この内のどれかを使ってcacheを無効化しましょう。

まとめ

開発してる時は「詰まった!!!トラップだ!!!なんだコレは!!!」とパニクっていたのですが、後から振り返ると至極丁寧にすべてドキュメントに記載が有りました。 公式ドキュメント読むの大事ですね。

Masayuki Yamaji

Masayuki Yamaji

Fusicの一番年老いた山路です。