Real World Example

Search Box Like Swiggy or Amazon

When you type in Swiggy's search box and press Enter, the URL changes to something like /search?q=biryani. The URL is the source of truth, so the result page can be shared and reloaded. ShopEase does the same:

components/SearchBox.tsx

'use client';

import { useRouter, useSearchParams } from 'next/navigation';
import { useState } from 'react';

export default function SearchBox() {
  const router = useRouter();
  const params = useSearchParams();
  const [q, setQ] = useState(params.get('q') ?? '');

  function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const text = q.trim();
    if (!text) return;
    router.push('/search?q=' + encodeURIComponent(text));
  }

  return (
    <form onSubmit={onSubmit} role="search">
      <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search for products" />
      <button type="submit">Search</button>
    </form>
  );
}

Building the URL Safely

Example

Always encode user text before putting it in a URL. URLSearchParams does it for you:

function searchUrl(q: string, filters: Record<string, string> = {}): string {
  const params = new URLSearchParams({ q: q.trim(), ...filters });
  return '/search?' + params.toString();
}

console.log(searchUrl('chicken biryani'));
console.log(searchUrl('  shoes & socks ', { sort: 'price_asc' }));
console.log(searchUrl('100% cotton', { page: '2' }));

const parsed = new URLSearchParams('q=shoes+%26+socks&sort=price_asc');
console.log(parsed.get('q'), '|', parsed.get('sort'));

Output

/search?q=chicken+biryani
/search?q=shoes+%26+socks&sort=price_asc
/search?q=100%25+cotton&page=2
shoes & socks | price_asc