【App Router】Next.js13でURLのクエリパラメーターを取得する方法
概要
Next.13のApp Routerでクエリパラメータを取得する方法で詰まったので、備忘録を残します。
従来はuseRouter
を使って取得する方法が一般的だと思いますが、そのまま利用すると以下のようなエラーが発生します。
ReactServerComponentsError:
You have a Server Component that imports next/router. Use next/navigation instead.
Learn more: https://nextjs.org/docs/app/api-reference/functions/use-router
環境
- Next.js 13.4
- App Router
コード
クライアントコンポーネントで取得する場合
こちらの方法は簡単です。
検索すれば、すぐ出てくると思います。
"use client";
import { useSearchParams } from "next/navigation";
export default function Page() {
const searchParams = useSearchParams();
const pageNum = searchParams.get("page");
return (
<>
<h1>Page</h1>
<p>page: {pageNum}</p>
</>
);
}
参考: Functions: useSearchParams | Next.js
サーバーコンポーネントで取得する場合
useSearchParamsの注意点
Next.jsのドキュメントに"use client"
を使ってクライアントコンポーネントにすると「そのファイルにインポートされた他のすべてのモジュール (子コンポーネントを含む) はクライアントバンドルの一部とみなされます」とあるように、できるだけサーバーコンポーネントにしたいケースがあると思います。
Once "use client" is defined in a file, all other modules imported into it, including child components, are considered part of the client bundle.
参考: Getting Started: React Essentials | Next.js
ですが、useSearchParams
はクライアントコンポーネントでのみ利用できるので、下記のように"use client"
を指定せず、クライアントコンポーネントにしないとエラーが発生します。
import { useSearchParams } from "next/navigation";
export default function Page() {
const searchParams = useSearchParams();
const pageNum = searchParams.get("page");
return (
<>
<h1>Page</h1>
<p>page: {pageNum}</p>
</>
);
}
Error: useSearchParams only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component
ここで詰まりました。
解決法
解決方法は、至ってシンプルです。
propsにsearchParams
を指定して、そこから取得してあげることでサーバーコンポーネントでクエリパラメータを取得できます。
export default function Page({
params,
searchParams,
}: {
params: { slug: string };
searchParams: { [key: string]: string | string[] | undefined };
}) {
const pageNum = searchParams.page;
return (
<>
<h1>Page</h1>
<p>page: {pageNum}</p>
</>
);
}
参考: File Conventions: page.js | Next.js
やはり、新しいものを触る時はドキュメントを読み込むことが大事ですね。
読んでいただき、ありがとうございました。
Discussion