nextjsfetchparamsMenengah4 mnt baca

Fetch dengan Params & SearchParams

Menggabungkan route dinamis dan query string untuk fetch data.

Dua cara URL memberi tahu data apa yang diambil

Bayangkan seorang pustakawan. Kamu memberinya dua informasi: nomor rak ("rak 5") dan catatan filter ("yang terbit tahun 2024 saja"). Nomor rak menentukan lokasi pasti, catatan filter menyaring isinya. Di Next.js, params adalah nomor rak (segmen dinamis seperti [id]), sedangkan searchParams adalah catatan filter (query string seperti ?page=2&sort=murah).

Kenapa konsep ini ada? Halaman dinamis tidak bisa punya data yang di-hardcode. Halaman /blog harus tahu halaman ke berapa yang diminta, halaman /shop/elektronik harus tahu kategorinya. Next.js menyuntikkan keduanya langsung sebagai props ke Server Component, jadi kamu tidak perlu parsing URL manual dengan window.location (yang bahkan tidak ada di server).

Satu hal penting di Next.js 15+: params dan searchParams adalah Promise, jadi harus di-await sebelum dipakai.

tsx
// app/blog/page.tsx?page=2
// Contoh 1: paginasi lewat query string
export default async function Blog({
  searchParams,
}: {
  searchParams: Promise<{ page?: string }>;
}) {
  const { page = "1" } = await searchParams; // default aman bila query hilang
  const res = await fetch(
    `https://api.example.com/posts?page=${page}&limit=5`
  );
  const posts = await res.json();

  return (
    <>
      <PostList posts={posts} />
      <nav>
        <a href={`/blog?page=${Number(page) - 1}`}>Prev</a>
        <a href={`/blog?page=${Number(page) + 1}`}>Next</a>
      </nav>
    </>
  );
}

Perhatikan pola amannya: selalu sediakan nilai default (page = "1") karena query string bisa tidak ada, dan konversi tipe dilakukan eksplisit (Number(page)).

Kombinasi params + searchParams

tsx
// app/shop/[category]/page.tsx?sort=murah
// Contoh 2: kategori dari URL, urutan dari query
export default async function Shop({
  params,
  searchParams,
}: {
  params: Promise<{ category: string }>;
  searchParams: Promise<{ sort?: string }>;
}) {
  const { category } = await params;
  const { sort = "populer" } = await searchParams;

  const items = await getItems(category, sort); // helper di lib/
  return <Grid items={items} />;
}

Di sini category datang dari segmen dinamis [category], sedangkan sort dari query string. Keduanya digabung menjadi satu pemanggilan fetch.

Kenapa searchParams membuat halaman jadi dinamis?

Nilai query string baru diketahui saat request masuk, jadi Next.js tidak bisa me-render halaman ini sepenuhnya saat build (full SSG). Halaman otomatis menjadi dynamic. Ini bukan bug, ini wajar untuk halaman filter, pencarian, dan paginasi. Kalau kamu butuh halaman yang tetap statis, hindari membaca searchParams di situ dan pindahkan logika filter ke Client Component.

Catatan teknis: Selalu validasi nilai dari URL sebelum dipakai di fetch. Query string adalah input user: batasi nilainya ke daftar yang diizinkan (misalnya sort hanya boleh "populer", "murah", "baru"), dan pakai encodeURIComponent bila nilainya disisipkan ke URL API. Jangan pernah percaya URL mentah.

Tantangan

Paginasi

Buat halaman blog dengan query ?page=N yang fetch 5 post per halaman dari API publik. Tambahkan tombol Prev/Next berupa Link yang update query param.