Bermain Search Params dengan nuqs di Next.js App Router
Zakiego
@zakiego
Daftar Isi
Abstrak
nuqs
merupakan library search params state manager untuk Next.js.
Default behavior dari nuqs
adalah client first, artinya, saat melakukan update search params, web tidak akan melakukan re-render. Ini hal yang bagus jika value dari search params hanya perlu dibaca melalui client side.
Namun, jika value perlu dibaca oleh server, maka tidak akan terbaca perubahannya. Untuk memicu re-render agar perubahan terbaca oleh server maka perlu ditambah opsi { shallow: false }
.
Berbeda halnya dengan next-query-params
yang mengusung server first, artinya setiap perubahan value akan langsung terbaca oleh server.
Rasakan perbedaan antara search params client side dan server side pada
nuqs
di nuqs-playground.vercel.appSedangkan untuk
next-query-params
bisa dicoba di seach-params-playground.vercel.app
Pendahuluan
Tulisan ini merupakan lanjutan dari tulisan Membuat Komponen Search di Next.js App Router. Jika sebelumnya kita menggunakan library next-query-params
, untuk me-manage search params, kali ini kita akan bermain dengan nuqs
.
Sebenarnya sebelum ini, saya sempat mencicipi nuqs
. Namun karena keterbatasan pengetahuan, akhirnya saya tidak melanjutkannya.
Terima kasih untuk Mas @alfonsusac yang men-trigger saya untuk kembali membaca lebih dalam dokumentasi nuqs
.
Selayang Pandang
nuqs
mendefinisikan dirinya sebagai, "Type-safe search params state manager for Next.js".
Mari kita mulai. Tentu saja, framework yang digunakan dalam tulisan ini adalah Next.js.
Pertama, install nuqs
.
pnpm add nuqs
Buat component file yang berisi <input/>
, kemudian value onChange
kita teruskan menjadi search params dengan useQueryState
.
// src/app/client.tsx
'use client'
import { useQueryState } from 'nuqs'
export function Demo() {
const [name, setName] = useQueryState("name");
return (
<>
<input value={name || ""} onChange={(e) => setName(e.target.value)} />
<p>Hello, {name}!</p>
</>
);
}
Mengan perlu menuliskan "use client" pada baris paling atas?
Karena, sejak diperkenalkannya paradigma App Router di Next.js, default dari setiap component adalah server component. Sedangkan, dalam kasus ini, kita memerlukan
onChange
dari<input/>
yang merupakan client component. Sebab itu, perlu untuk menuliskan "use client" pada baris teratas, untuk memberi tahu React, bahwa ini merupakan client component (Client Components).
Terakhir, import component <Demo/>
yang sudah kita buat ke /src/app/hello/page.tsx
.
Hasilnya, setiap kali memasukkan value di <input/>
, maka search params akan langsung ter-update.
Contohnya, dari example.com/hello
akan berubah menjadi example.com/hello?name=zaki
.
Untuk contoh lebih banyak, bisa dilihat di nuqs.47ng.com/playground.
Perbedaan nuqs dengan next-query-params
Sebelumnya, saya sempat menggunakan nuqs pada tweet ini. Perbedaan paling mencolok antara nuqs
dan next-query-params
adalah:
nuqs
berjalan di atas client-first- sedangkan,
next-query-params
adalah server-first
Apa bedanya?
Kamu bisa merasakan langsung perbedaan client-first (nuqs-playground.vercel.app/nuqs-client) dan server-first (nuqs-playground.vercel.app/nuqs-server)
Dengan nuqs
mengusung client-first, maka, kita tidak bisa mengakses search params dari server side.
Misal, kita mengunjungi halaman example.com/hello
.
Kemudian, saat mengetikkan input nama, URL berubah menjadi example.com/hello?name=zaki
.
Meski URL berubah, namun karena nuqs
adalah client first, maka value dari name
yang kita ambil dari search params akan tetap kosong, jika menggunakan server side.
nuqs
secara default tidak men-trigger pembaruan halaman ke server. Sehingga meski kita URL di browser kita berubah menjadi example.com/hello?name=zaki
, sejatinya, server masih menganggap kita berada pada halaman example.com/hello
saja.
interface Props {
searchParams: {
name?: string;
};
}
export default async function Page(props: Props) {
const { searchParams } = props;
const { name } = searchParams;
return (
<div>
value from server: {name}
</div>
);
}
Namun berbeda halnya pada client component, seperti pada <Demo/>
tadi.
Izinkan saya meletakkan kodenya sekali lagi.
// src/app/client.tsx
'use client'
import { useQueryState } from 'nuqs'
export function Demo() {
const [name, setName] = useQueryState("name");
return (
<>
<input value={name || ""} onChange={(e) => setName(e.target.value)} />
<p>Hello, {name}!</p>
</>
);
}
Di kode tersebut, value dari name
akan langsung terbaca, meski kita tidak melakukan pembaruan halaman ke server.
Hal ini berkebalikan dengan next-query-params
, setiap kali melakukan update value pada <input/>
, maka ia akan memicu pembaruan halaman.
Alhasil, saat URL terupdate dari example.com/hello
menjadi example.com/hello?name=zaki
, server langsung mengenali bahwa kita sudah berada di URL example.com/hello?name=zaki
.
nuqs namun Server Side
Setelah melakukan pembacaan lebih seksama, meski nuqs
adalah client-first, kita tetap bisa menjalan re-render, yaitu dengan menambahkan { shallow: false }
.
Docs nuqs.47ng.com/docs/options
useQueryState('foo', { shallow: false })
Dengan setting-an di atas, maka kita bisa mendapatkan search params melalui server side.
Kamu bisa mencobanya di sini nuqs-playground.vercel.app/nuqs-server.
Buah Tangan
Berikut beberapa reply dari author nuqs
langsung:
Selain itu, nuqs
juga ternyata digunakan oleh vercel.com 😅
Penutup
nuqs
memiliki DX (developer experience) yang lebih mudah ketimbang next-query-params
, karena tidak perlu menambahkan kode pada fitur layout.
Namun, karena nuqs
adalah client-first, maka value dari search params, perubahan value tidak bisa didapat secara langsung pada server side, kecuali menggunakan { shallow: false }
. Berbeda dengan next-query-params
yang sedari awal adalah server-first, sehingga perubahan value langsung bisa dibaca oleh server.
Alhasil, semua kembali ke sisi developer. Pertanyaannya:
- Apakah kamu melakukan fetch pada server-side atau client side?
- Selanjutnya, apakah value search params perlu untuk bisa dibaca server? Karena pada beberapa kasus, search params tidak harus langsung bisa dibaca oleh server
Sekian dan terima kasih.
Selesai ditulis hari Kamis, 11 April 2024 pada 13:39, atau hari kedua lebaran.