useSearchParamsを使うコンポーネントはSuspenseで囲っておこう
2023/10/04

useSearchParamsを使うコンポーネントはSuspenseで囲っておこう

1 min to read

運営しているサイトのトップページだけ内部リンクゼロになっていて、どうやらGoogleクローラーがページ全体をクローリングできていないようでした。

原因を探る為、ページのソースを表示すると<html id="__next_error__">となっていて、ページソースが丸ごとレンダリングされていませんでした。

エラーの原因

検索していると以下の記事を見つけました。

Next.js のApp Dirでは、ルートが静的にレンダリングされる場合useSearchParams()を呼び出すと、最も近いSuspense境界までのツリーがクライアントサイドレンダリングされます。
useSearchParamsを使用するコンポーネントをSuspense境界で囲むことで、クライアントサイドでレンダリングされるルートの部分を減らすことができます。

私の場合は検索フォームをトップページに設置しており、検索フォームコンポーネント内でuseSearchParams()を使っていました。

Before

"use client";

import { Suspense } from "react";
import { useSearchParams } from "next/navigation";

export const SearchForm = () => {
  const searchParams = useSearchParams();
  return (
    ...
  );
};

After

"use client";

import{ Suspense } from "react";
import { useSearchParams } from "next/navigation";

export const Search = () => {
  const searchParams = useSearchParams();
  return (
    ...
  );
};

export const SearchForm = () => {
  return (
    <Suspense>
      <Search />
    </Suspense>
  );
};

これで解決しました。

自戒: 公式ドキュメントを読もう

よく見たら公式にも書いてました...😭

このエラーなんですが、

  • 開発環境ではエラーが表示されない
  • コンソールにもエラーが表示されない
  • ぱっと見は普通に見れる

という感じで、本番環境でしか発生しないうえコンソールにもエラーが表示されないのでとても気付きにくいわりにはページソースが丸ごとレンダリングされないというSEO面で大きな被害を及ぼすエラーなので、みなさん気をつけてください😭