検索をサーバーで

絞り込みを URL に持たせる

React で作った検索は、入力した文字を useState に持っていました。動きはしますが、絞り込んだ結果を人に送れません。URL がずっと /items のままだからです。

Next.js では、絞り込みの条件を URL のクエリに置きます。/items?category=shoes を開けば誰でも同じ結果が見られますし、ブラウザの戻るボタンも効きます。検索エンジンもこの URL を1ページとして扱えます。

searchParams で受け取る

クエリはページの searchParams という props に入ってきます。params と同じく Promise なので await して開けます。

type Props = { searchParams: Promise<{ category?: string }>; }; export default async function ItemsPage({ searchParams }: Props) { const { category } = await searchParams; const url = category ? `/api/items?category=${category}` : "/api/items"; const res = await fetch(url); const items = await res.json(); return <p>{items.length}</p>; }

型は省略できるものとして書く

クエリは付いていないこともあります。/items で開かれれば categoryundefined です。だから型は category?: string のように省略できる形にします。

無いときにどうするかも決めておきます。上の例では、条件が無ければ絞り込まない URL を使っています。空文字を渡してしまうと、名前が空の商品を探しにいく形になり、結果が0件になります。

演習

一覧ページを searchParams で絞り込めるようにします。

ヒント

app/items/page.tsx
layout.tsx
app/page.tsx
mock-api.json
プレビュー

できているか

  • くつを選ぶと2件に絞り込まれる
  • キッチンを選ぶと1件になる
  • すべてに戻すと5件に戻る
  • searchParams を await して使っている