Next.js
Search
Implementing search functionality using URL query parameters in Next.js App Router.
Search Component: Updating the URL search params on user input.
app/components/Search.tsx
TSX
'use client';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { useTransition } from 'react';
export default function Search() {
const searchParams = useSearchParams();
const pathname = usePathname();
const { replace } = useRouter();
const [isPending, startTransition] = useTransition();
function handleSearch(term: string) {
const params = new URLSearchParams(searchParams);
if (term) {
params.set('query', term);
} else {
params.delete('query');
}
startTransition(() => {
replace(`${pathname}?${params.toString()}`);
});
}
return (
<input
type="text"
placeholder="Search..."
className="border p-2 rounded"
onChange={(e) => handleSearch(e.target.value)}
defaultValue={searchParams.get('query') || ''}
/>
);
}
Server Component: Reading search params to fetch data.
app/page.tsx
TSX
import Search from './components/Search';
import { Suspense } from 'react';
export default async function Page({
searchParams,
}: {
searchParams?: { query?: string };
}) {
const query = searchParams?.query || '';
// Example data fetch based on search query
// const data = await db.items.findMany({ where: { title: { contains: query } } });
return (
<main className="p-4">
<h1 className="text-2xl font-bold mb-4">Item Search</h1>
<Search />
<Suspense key={query} fallback={<p>Loading results...</p>}>
<div className="mt-4">
<p>Showing results for: <strong>{query || 'All items'}</strong></p>
{/* Render fetched data here */}
</div>
</Suspense>
</main>
);
}