Nextjs:searchParams
2026年4月9日propsの中身
const page = async (props) => {
console.log(props);
// { params: Promise { <pending> }, searchParams: Promise { <pending> } }page/layout.tsxの(props)の中身は2つに分かれるparams/[slug]のような動的ルートに対応した値
searchParamsURLのクエリパラメータ。
?key=valueのような形
クエリパラメータ
URLの「?」以降に付けるパラメータのこと
?query=next&page=2のように複数設定できる以下はpropsの
searchParamsを使わず、Web標準のクエリパラメータ取得の仕方
// クライアント
useEffect(() => {
const searchParams = new URLSearchParams(window.location.search).get(
"page",
);
}, []);
// サーバー
const paramas = new URL(request.url).searchParams.get("page");クエリの取得
"http://localhost:3000/search?query=test"からqueryを取得
// クライアント
const searchParams = useSearchParams();
const query = searchParams.get("query");
// サーバー
const Page = async ({ searchParams } : searchParams: Promise<{ query?: string }>;
) => {
const params = await searchParams;
const query = params.query;サーバー側は
page.tsxとlayout.tsxからしか取得できない一方、クライアント側はどのクライントコンポーネントでもuseSearchParamsが使える。
クエリの変更:クライアントのみ
クエリの変更をサーバーサイドで行うことはできない。クエリの生成はNextjsに限らずaタグのhref属性から行える。
?query=queryをセット・変更:
const SetQuery = () => {
const [query, setQuery] = useState("");
const searchParams = useSearchParams();
const pathname = usePathname();
const router = useRouter();
const handleSearch = (query: string) => {
const params = new URLSearchParams(searchParams);
params.set("query", query);
router.push(`${pathname}?${params.toString()}`);
};
---
<input
className="border-4"
type="text"
value={query}
onChange={(e) => {
setQuery(e.target.value);
handleSearch(e.target.value);
}}
/>new URLSearchParams(searchParams):useSearchParams()では読み取り専用のsearchParamsオブジェクトが取得されるので、queryの削除やセットを行いたい場合はブラウザ標準のURLSearchParamsをインスタンス化する必要がある。
URLSearchParamsの引数には現在のクエリ( =searchParams)を渡す。router.push/replaceでセットparams.setでURLSearchParamsオブジェクトは更新されるが、router.push / replaceでそのURLに遷移させる必要がある。
使用例:SearchInput
"use client";
import { Input } from "@/components/ui/input";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useDebouncedCallback } from "use-debounce";
const TestSearch = () => {
const searchParams = useSearchParams();
const { replace } = useRouter();
const pathname = usePathname();
const handleSearch = useDebouncedCallback((query: string) => {
const params = new URLSearchParams(searchParams);
if (query.length >= 3) {
params.set("query", query);
} else {
params.delete("query");
}
replace(`${pathname}?${params.toString()}`);
}, 250);
return (
<Input
onChange={(e) => handleSearch(e.target.value)}
defaultValue={searchParams.get("query")?.toString()}
/>
);
};
export default TestSearch;fetch
APIルートもURLなのでクエリパラメータをつけてfetchすることが出来る。
fetch:
fetch(`/api/keyword?keyword=test`)route.ts:
export async function GET(request: NextRequest) {
const keyword = request.nextUrl.searchParams.get("keyword") ?? "";
// Web標準の場合
const url = new URL(req.url);
const keyword = url.searchParams.get('keyword') ?? '';Web標準の場合
req.urlはただの文字列なのでnew URL()でURLオブジェクトに変換しないとプロパティにアクセスできない。