{"id":36114,"date":"2025-12-08T13:31:48","date_gmt":"2025-12-08T10:31:48","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/"},"modified":"2025-12-08T13:31:48","modified_gmt":"2025-12-08T10:31:48","slug":"next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/","title":{"rendered":"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim"},"content":{"rendered":"<p><body><\/p>\n<p>Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131 kayna\u011f\u0131 olabilen bir konudur. Genellikle string olarak gelen bu parametreleri elle ayr\u0131\u015ft\u0131rmak, do\u011fru tiplere d\u00f6n\u00fc\u015ft\u00fcrmek ve uygulama state&#8217;i ile senkronize etmek, hem zaman al\u0131c\u0131 hem de hata yapmaya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Neyse ki, <code>nuqs<\/code> gibi modern k\u00fct\u00fcphaneler bu zorluklar\u0131 a\u015fmak i\u00e7in g\u00fc\u00e7l\u00fc ve zarif bir \u00e7\u00f6z\u00fcm sunuyor. Bu makalede, <code>nuqs<\/code>&#8216;un Next.js projelerinizde URL arama parametrelerini nas\u0131l tip-g\u00fcvenli, reaktif ve zahmetsiz bir \u015fekilde y\u00f6netmenizi sa\u011flad\u0131\u011f\u0131n\u0131 derinlemesine inceleyece\u011fiz.<\/p>\n<p>E\u011fer siz de Next.js projelerinizde URL&#8217;deki sorgu parametrelerinin da\u011f\u0131n\u0131kl\u0131\u011f\u0131yla m\u00fccadele ediyorsan\u0131z, bu makale size arad\u0131\u011f\u0131n\u0131z netli\u011fi ve pratik \u00e7\u00f6z\u00fcmleri sunacak. Kod \u00f6rnekleri, ger\u00e7ek d\u00fcnya senaryolar\u0131 ve ileri d\u00fczey ipu\u00e7lar\u0131 ile <code>nuqs<\/code>&#8216;un sundu\u011fu avantajlar\u0131 ke\u015ffedecek, b\u00f6ylece kullan\u0131c\u0131 deneyiminizi geli\u015ftirirken geli\u015ftirme s\u00fcrecinizi de b\u00fcy\u00fck \u00f6l\u00e7\u00fcde kolayla\u015ft\u0131racaks\u0131n\u0131z. Haz\u0131rsan\u0131z, URL parametre y\u00f6netimini bir sonraki seviyeye ta\u015f\u0131yal\u0131m!<\/p>\n<p>Web uygulamalar\u0131n\u0131n dinamik do\u011fas\u0131 gere\u011fi, kullan\u0131c\u0131 etkile\u015fimlerini veya sayfa durumunu URL&#8217;ler arac\u0131l\u0131\u011f\u0131yla iletmek yayg\u0131n bir y\u00f6ntemdir. \u00d6zellikle Next.js gibi \u00e7er\u00e7evelerde, bir kullan\u0131c\u0131n\u0131n filtreledi\u011fi bir \u00fcr\u00fcn listesini, g\u00f6r\u00fcnt\u00fcledi\u011fi sayfa numaras\u0131n\u0131 veya uygulad\u0131\u011f\u0131 bir s\u0131ralama se\u00e7ene\u011fini URL&#8217;de arama parametreleri (<code>?kategori=elektronik&sayfa=2&s\u0131rala=fiyat<\/code> gibi) olarak tutmak, hem SEO a\u00e7\u0131s\u0131ndan faydal\u0131d\u0131r hem de kullan\u0131c\u0131lar\u0131n belirli bir durumu do\u011frudan payla\u015fmas\u0131n\u0131 veya yer i\u015faretlemesini sa\u011flar. Ancak bu pratik yakla\u015f\u0131m\u0131n beraberinde getirdi\u011fi baz\u0131 zorluklar vard\u0131r ve bunlar geli\u015ftiriciler i\u00e7in ciddi ba\u015f a\u011fr\u0131lar\u0131na yol a\u00e7abilir.<\/p>\n<p>Bu parametrelerin ilk ve en b\u00fcy\u00fck sorunu, taray\u0131c\u0131 taraf\u0131ndan her zaman bir string olarak i\u015flenmesidir. Sayfa numaras\u0131 (<code>sayfa=2<\/code>) asl\u0131nda bir say\u0131 olmas\u0131na ra\u011fmen, JavaScript taraf\u0131na <code>\"2\"<\/code> olarak ula\u015f\u0131r. Bir filtrenin aktif olup olmad\u0131\u011f\u0131n\u0131 belirten boolean bir de\u011fer (<code>aktif=true<\/code>) ise yine <code>\"true\"<\/code> string&#8217;i olarak gelir. Bu durum, her parametreyi manuel olarak do\u011fru veri tipine d\u00f6n\u00fc\u015ft\u00fcrme ihtiyac\u0131n\u0131 do\u011furur. \u00d6rne\u011fin, bir sayfa numaras\u0131n\u0131 kullanmadan \u00f6nce <code>parseInt()<\/code> ile say\u0131ya \u00e7evirmeniz veya bir boolean de\u011feri <code>\"true\" === value<\/code> \u015feklinde kontrol etmeniz gerekir. Bu manuel d\u00f6n\u00fc\u015ft\u00fcrmeler, uygulaman\u0131n farkl\u0131 yerlerinde tekrarlanma e\u011filimindedir ve kolayca hata yap\u0131lmas\u0131na neden olabilir. Yanl\u0131\u015f bir d\u00f6n\u00fc\u015f\u00fcm veya eksik bir kontrol, uygulaman\u0131zda beklenmedik davran\u0131\u015flara veya hatalara yol a\u00e7abilir.<\/p>\n<p>Next.js&#8217;in App Router yap\u0131s\u0131nda veya Pages Router&#8217;da kullan\u0131lan <code>useSearchParams<\/code> hook&#8217;u, URL&#8217;deki arama parametrelerine eri\u015fim sa\u011flar, ancak \u00f6nemli bir k\u0131s\u0131tlamas\u0131 vard\u0131r: yaln\u0131zca okuma (read-only) yetene\u011fine sahiptir. Yani, bu hook arac\u0131l\u0131\u011f\u0131yla URL&#8217;deki parametreleri okuyabilir, ancak do\u011frudan de\u011fi\u015ftiremezsiniz. Parametreleri de\u011fi\u015ftirmek istedi\u011finizde, genellikle <code>next\/navigation<\/code> mod\u00fcl\u00fcnden <code>useRouter<\/code> hook&#8217;unu kullanarak programatik olarak navigasyon (<code>router.push()<\/code> veya <code>router.replace()<\/code>) yapman\u0131z gerekir. Bu da demektir ki, basit bir arama kutusuna yaz\u0131lan her karakterde URL&#8217;yi g\u00fcncellemek veya bir filtre se\u00e7ildi\u011finde URL&#8217;ye yeni bir parametre eklemek i\u00e7in karma\u015f\u0131k bir state y\u00f6netimi ve router etkile\u015fimi kurman\u0131z gerekir. Bu yakla\u015f\u0131m, gereksiz yeniden render&#8217;lara veya istenmeyen tam sayfa yenilemelerine yol a\u00e7abilir, bu da kullan\u0131c\u0131 deneyimini olumsuz etkiler.<\/p>\n<p>Dahas\u0131, karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 (\u00f6rne\u011fin bir dizi kategori se\u00e7imi veya bir fiyat aral\u0131\u011f\u0131 objesi) URL&#8217;de temsil etmek ve bunlar\u0131 g\u00fcvenli bir \u015fekilde ayr\u0131\u015ft\u0131r\u0131p serialize etmek ba\u015fl\u0131 ba\u015f\u0131na bir meydan okumad\u0131r. Geli\u015ftiriciler genellikle bu t\u00fcr durumlar i\u00e7in kendi \u00f6zel hook&#8217;lar\u0131n\u0131 veya yard\u0131mc\u0131 fonksiyonlar\u0131n\u0131 yazmak zorunda kal\u0131r, bu da kod tekrar\u0131na, bak\u0131m zorlu\u011funa ve potansiyel g\u00fcvenlik a\u00e7\u0131klar\u0131na yol a\u00e7ar. Bu kadar \u00e7ok manuel i\u015flem ve k\u0131s\u0131tlama, geli\u015ftirme s\u00fcrecini yava\u015flat\u0131r ve hata ay\u0131klamay\u0131 zorla\u015ft\u0131r\u0131r. \u0130\u015fte tam da bu noktada, <code>nuqs<\/code> gibi k\u00fct\u00fcphaneler devreye girerek bu geleneksel zorluklar\u0131 modern ve tip-g\u00fcvenli bir yakla\u015f\u0131mla \u00e7\u00f6zmeyi hedefler.<\/p>\n<h2>nuqs Nedir ve Next.js&#8217;te URL Parametre Y\u00f6netimine Nas\u0131l Devrim Getirir?<\/h2>\n<p>Modern web uygulamalar\u0131, kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fcn karma\u015f\u0131kl\u0131\u011f\u0131 artt\u0131k\u00e7a, taray\u0131c\u0131 URL&#8217;sinin de uygulama state&#8217;inin \u00f6nemli bir par\u00e7as\u0131 haline gelmesini gerektiriyor. Ancak yukar\u0131da bahsetti\u011fimiz gibi, Next.js&#8217;in yerle\u015fik mekanizmalar\u0131 bu senkronizasyonu sa\u011flamada baz\u0131 temel eksikliklere sahip. \u0130\u015fte tam bu noktada <code>nuqs<\/code>, Next.js uygulamalar\u0131n\u0131zdaki URL arama parametreleri y\u00f6netimini ba\u015ftan a\u015fa\u011f\u0131 yeniden tan\u0131mlayan g\u00fc\u00e7l\u00fc ve hafif bir k\u00fct\u00fcphane olarak \u00f6ne \u00e7\u0131k\u0131yor. Temel felsefesi, geli\u015ftiricilere tip-g\u00fcvenli\u011fi, reaktiflik ve kullan\u0131m kolayl\u0131\u011f\u0131n\u0131 bir arada sunarak, URL&#8217;leri uygulama state&#8217;inizin birinci s\u0131n\u0131f bir vatanda\u015f\u0131 haline getirmektir.<\/p>\n<p><code>nuqs<\/code>, \u00f6zellikle React&#8217;\u0131n <code>useState<\/code> hook&#8217;undan ilham alan bir API sunar. T\u0131pk\u0131 bir bile\u015fenin i\u00e7 state&#8217;ini y\u00f6netti\u011finiz gibi, <code>useQueryState<\/code> ve <code>useQueryStates<\/code> gibi hook&#8217;lar arac\u0131l\u0131\u011f\u0131yla URL arama parametrelerini de y\u00f6netebilirsiniz. Bu, geli\u015ftiricilerin URL parametrelerini d\u00fc\u015f\u00fcnme ve bunlarla etkile\u015fim kurma bi\u00e7iminde devrim yarat\u0131r. Art\u0131k manuel ayr\u0131\u015ft\u0131rma, serile\u015ftirme ve router etkile\u015fimiyle u\u011fra\u015fmak yerine, t\u0131pk\u0131 lokal bir state&#8217;i g\u00fcncelliyormu\u015f gibi URL parametrelerini do\u011frudan g\u00fcncelleyebilir ve bu g\u00fcncellemelerin reaktif bir \u015fekilde bile\u015fenlerinize yans\u0131d\u0131\u011f\u0131n\u0131 g\u00f6rebilirsiniz. Bu sayede, Next.js&#8217;in sa\u011flad\u0131\u011f\u0131 h\u0131zl\u0131 sayfa ge\u00e7i\u015fleri (client-side routing) ve g\u00fc\u00e7l\u00fc sunucu taraf\u0131 render (SSR) yetenekleriyle kusursuz bir uyum i\u00e7inde \u00e7al\u0131\u015f\u0131r.<\/p>\n<h3><code>nuqs<\/code>&#8216;un Temel \u00d6zellikleri ve Avantajlar\u0131 Nelerdir?<\/h3>\n<ul>\n<li><strong>Tip \u00c7\u0131kar\u0131m\u0131 (Type Inference) ve Tip-G\u00fcvenli\u011fi:<\/strong> <code>nuqs<\/code>&#8216;un en dikkat \u00e7ekici \u00f6zelli\u011fi, TypeScript ile m\u00fckemmel entegrasyonudur. Tan\u0131mlad\u0131\u011f\u0131n\u0131z URL parametrelerinin tiplerini otomatik olarak \u00e7\u0131kar\u0131r ve bu sayede yanl\u0131\u015f tipte de\u011fer atamalar\u0131n\u0131 veya okumalar\u0131n\u0131 derleme zaman\u0131nda yakalaman\u0131z\u0131 sa\u011flar. Bu, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k projelerde hata olas\u0131l\u0131\u011f\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde azalt\u0131r ve geli\u015ftirici deneyimini art\u0131r\u0131r.<\/li>\n<li><strong>Otomatik Ayr\u0131\u015ft\u0131rma ve Serile\u015ftirme:<\/strong> Say\u0131lar (<code>number<\/code>), boolean&#8217;lar (<code>boolean<\/code>) ve diziler (<code>array<\/code>) gibi temel veri tipleri i\u00e7in dahili ayr\u0131\u015ft\u0131r\u0131c\u0131lar (parsers) ve serile\u015ftiriciler (serializers) sunar. Bu, elle <code>parseInt()<\/code> veya <code>JSON.stringify()<\/code> gibi i\u015flemleri yapma ihtiyac\u0131n\u0131 ortadan kald\u0131r\u0131r. Sadece parametrenizin tipini belirtmeniz yeterlidir, gerisini <code>nuqs<\/code> halleder.<\/li>\n<li><strong>\u00d6zel Ayr\u0131\u015ft\u0131r\u0131c\u0131lar (Custom Parsers):<\/strong> Dahili tiplerin \u00f6tesine ge\u00e7meniz gerekti\u011finde, kendi \u00f6zel ayr\u0131\u015ft\u0131r\u0131c\u0131lar\u0131n\u0131z\u0131 tan\u0131mlaman\u0131za olanak tan\u0131r. Bu sayede <code>Date<\/code> objeleri, karma\u015f\u0131k JSON yap\u0131lar\u0131 veya belirli bir formatta string&#8217;ler gibi \u00f6zel veri tiplerini bile URL&#8217;de g\u00fcvenli bir \u015fekilde y\u00f6netebilirsiniz.<\/li>\n<li><strong>Reaktif ve G\u00fcncel State:<\/strong> <code>useQueryState<\/code> hook&#8217;u, t\u0131pk\u0131 <code>useState<\/code> gibi \u00e7al\u0131\u015f\u0131r. URL&#8217;deki bir parametre de\u011fi\u015fti\u011finde, ilgili bile\u015fenler otomatik olarak yeniden render edilir ve en g\u00fcncel de\u011fere eri\u015fir. Bu reaktif yap\u0131, kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fcz\u00fcn her zaman URL ile senkronize kalmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Debouncing Deste\u011fi:<\/strong> Arama kutular\u0131 gibi s\u0131k g\u00fcncelleme gerektiren alanlarda, her karakter giri\u015finde URL&#8217;yi g\u00fcncellemek performans\u0131 d\u00fc\u015f\u00fcrebilir. <code>nuqs<\/code>, bu durumu \u00f6nlemek i\u00e7in dahili <code>debounce<\/code> se\u00e7ene\u011fi sunar, b\u00f6ylece URL g\u00fcncellemelerini belirli bir gecikmeyle yapabilirsiniz.<\/li>\n<li><strong>Next.js App Router ve Pages Router Uyumlulu\u011fu:<\/strong> Hem Next.js&#8217;in eski Pages Router yap\u0131s\u0131nda hem de yeni App Router yap\u0131s\u0131nda sorunsuz bir \u015fekilde \u00e7al\u0131\u015f\u0131r. Client komponentlerinde <code>'use client'<\/code> direktifiyle, server komponentlerinde ise ba\u015flang\u0131\u00e7 de\u011ferlerini ayarlayarak rahatl\u0131kla kullan\u0131labilir.<\/li>\n<li><strong>Sunucu Taraf\u0131 G\u00fcvenli\u011fi (Server-Side Safety):<\/strong> <code>nuqs<\/code>, server component&#8217;lerde ba\u015flang\u0131\u00e7 de\u011ferlerini okuma yetene\u011fi sunarak, hem ilk y\u00fcklemede do\u011fru URL state&#8217;inin olmas\u0131n\u0131 sa\u011flar hem de SEO dostu URL&#8217;ler olu\u015fturman\u0131za yard\u0131mc\u0131 olur.<\/li>\n<\/ul>\n<p>Manuel URL y\u00f6netimine k\u0131yasla, <code>nuqs<\/code> geli\u015ftirici verimlili\u011fini inan\u0131lmaz derecede art\u0131r\u0131r. Daha az kod, daha az hata ve daha iyi bir geli\u015ftirme deneyimi demektir. URL parametrelerini art\u0131k sadece bir string y\u0131\u011f\u0131n\u0131 olarak de\u011fil, tip-g\u00fcvenli ve reaktif bir uygulama state&#8217;i par\u00e7as\u0131 olarak d\u00fc\u015f\u00fcnebilirsiniz. Bu, \u00f6zellikle karma\u015f\u0131k filtreleme, s\u0131ralama veya paginasyon i\u00e7eren Next.js uygulamalar\u0131 geli\u015ftirenler i\u00e7in ger\u00e7ek bir devrim niteli\u011findedir.<\/p>\n<h2>nuqs Kurulumu ve \u0130lk Ad\u0131mlar: Basit Bir Arama Parametresi Nas\u0131l Eklenir?<\/h2>\n<p>Next.js projelerinize <code>nuqs<\/code>&#8216;u entegre etmek olduk\u00e7a basittir ve birka\u00e7 ad\u0131mdan olu\u015fur. Bu b\u00f6l\u00fcmde, k\u00fct\u00fcphaneyi projenize nas\u0131l ekleyece\u011finizi ve basit bir arama parametresini URL&#8217;ye nas\u0131l dahil edece\u011finizi ad\u0131m ad\u0131m g\u00f6rece\u011fiz. Bu ilk ad\u0131mlar, <code>nuqs<\/code>&#8216;un temel mant\u0131\u011f\u0131n\u0131 anlaman\u0131za ve hemen kullanmaya ba\u015flaman\u0131za yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h3>Kurulum: Projenize nuqs&#8217;u Entegre Etmek<\/h3>\n<p><code>nuqs<\/code>&#8216;u projenize eklemek i\u00e7in favori paket y\u00f6neticinizi kullanabilirsiniz. Terminalinizi a\u00e7\u0131n ve a\u015fa\u011f\u0131daki komutlardan birini \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code>npm install nuqs\n# veya\nyarn add nuqs\n# veya\npnpm add nuqs\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut, <code>nuqs<\/code> k\u00fct\u00fcphanesini projenizin ba\u011f\u0131ml\u0131l\u0131klar\u0131na ekleyecektir. Kurulum tamamland\u0131ktan sonra, k\u00fct\u00fcphanenin sundu\u011fu hook'lar\u0131 Next.js bile\u015fenlerinizde kullanmaya haz\u0131rs\u0131n\u0131z demektir. Ek olarak bir <code>next.config.js<\/code> ayar\u0131 yapman\u0131za gerek yoktur, <code>nuqs<\/code> kutudan \u00e7\u0131kt\u0131\u011f\u0131 gibi \u00e7o\u011fu Next.js projesiyle uyumludur.<\/p>\n<h3>Temel Kullan\u0131m: <code>useQueryState<\/code> Hook'u ile Tan\u0131\u015fma<\/h3>\n<p><code>nuqs<\/code>'un kalbinde, React'\u0131n <code>useState<\/code> hook'una benzer bir aray\u00fcze sahip olan <code>useQueryState<\/code> hook'u yer al\u0131r. Bu hook, tek bir URL arama parametresini y\u00f6netmek i\u00e7in kullan\u0131l\u0131r. Gelin, bir arama kutusuna yaz\u0131lan terimi URL'ye nas\u0131l yans\u0131tabilece\u011finizi g\u00f6steren basit bir \u00f6rnekle ba\u015flayal\u0131m.<\/p>\n<pre><code>'use client';\n\nimport { useQueryState } from 'nuqs';\nimport { useEffect } from 'react';\n\nfunction SearchComponent() {\n  \/\/ 'q' ad\u0131nda bir URL arama parametresi tan\u0131ml\u0131yoruz.\n  \/\/ \u0130lk de\u011fer olarak bo\u015f bir string ('') kullanmas\u0131n\u0131 belirtiyoruz.\n  \/\/ shallow: false (varsay\u0131lan), tam sayfa yenileme yapar, true client-side navigasyon yapar.\n  const [searchTerm, setSearchTerm] = useQueryState('q', {\n    defaultValue: '',\n    shallow: false,\n  });\n\n  \/\/ searchTerm de\u011feri de\u011fi\u015fti\u011finde bir yan etki (side effect) olu\u015ftural\u0131m.\n  \/\/ Bu, URL'nin ve bile\u015fen state'inin senkronize oldu\u011funu g\u00f6sterir.\n  useEffect(() => {\n    console.log('Arama terimi URL\\'de de\u011fi\u015fti:', searchTerm);\n    \/\/ Bu noktada arama sonu\u00e7lar\u0131n\u0131 tetikleyebilirsiniz.\n  }, [searchTerm]);\n\n  return (\n    <div style={{ padding: '20px', border: '1px solid #ddd', borderRadius: '8px' }}>\n      <h3>\u00dcr\u00fcn Arama<\/h3>\n      <input\n        type=\"text\"\n        value={searchTerm || ''} \/\/ URL'de 'q' parametresi yoksa bo\u015f string g\u00f6ster\n        onChange={(e) => setSearchTerm(e.target.value)}\n        placeholder=\"Arama terimi girin...\"\n        style={{ padding: '8px', borderRadius: '4px', border: '1px solid #ccc', width: '300px' }}\n      \/>\n      {searchTerm && (\n        <p>\n          Mevcut arama: <strong>{searchTerm}<\/strong>{' '}\n          <button onClick={() => setSearchTerm(null)} style={{ marginLeft: '10px' }}>\n            Temizle\n          <\/button>\n        <\/p>\n      )}\n      <p style={{ fontSize: '0.9em', color: '#666' }}>\n        URL: <code>\/sayfa{searchTerm ? <code>?q=${searchTerm}<\/code> : ''}<\/code>\n      <\/p>\n    <\/div>\n  );\n}\n\nexport default SearchComponent;\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki kod blo\u011funda, <code>SearchComponent<\/code> ad\u0131nda basit bir React bile\u015feni olu\u015fturduk. Bu bile\u015fen, bir arama giri\u015fi (<code>input<\/code>) i\u00e7erir ve kullan\u0131c\u0131n\u0131n girdi\u011fi metni URL'deki <code>q<\/code> parametresiyle senkronize eder. \u0130\u015fte ad\u0131mlar\u0131n a\u00e7\u0131klamas\u0131:<\/p>\n<ol>\n<li><strong><code>'use client';<\/code>:<\/strong> Next.js App Router'da <code>useQueryState<\/code> gibi hook'lar client taraf\u0131nda \u00e7al\u0131\u015f\u0131r, bu y\u00fczden bu direktifi eklemeyi unutmay\u0131n.<\/li>\n<li><strong><code>import { useQueryState } from 'nuqs';<\/code>:<\/strong> Gerekli hook'u <code>nuqs<\/code> k\u00fct\u00fcphanesinden i\u00e7e aktar\u0131yoruz.<\/li>\n<li><strong><code>const [searchTerm, setSearchTerm] = useQueryState('q', { defaultValue: '', shallow: false });<\/code>:<\/strong>\n<ul>\n<li><code>'q'<\/code>: URL'de y\u00f6netmek istedi\u011fimiz parametrenin ad\u0131d\u0131r. Yani URL'de <code>?q=de\u011fer<\/code> \u015feklinde g\u00f6r\u00fcnecektir.<\/li>\n<li><code>{ defaultValue: '' }<\/code>: Bu parametre URL'de yoksa, <code>searchTerm<\/code>'in ba\u015flang\u0131\u00e7 de\u011feri bo\u015f bir string olacakt\u0131r. Bu, hem tip-g\u00fcvenli\u011fi sa\u011flar hem de server-side render durumlar\u0131nda bir ba\u015flang\u0131\u00e7 de\u011feri olmas\u0131n\u0131 garantiler.<\/li>\n<li><code>shallow: false<\/code>: Bu, bir parametre de\u011fi\u015fti\u011finde tam sayfa yenilemesi yap\u0131laca\u011f\u0131n\u0131 belirtir. E\u011fer sadece client-side routing ile URL'yi g\u00fcncellemek ve sayfa yenilemesi yapmamak isterseniz <code>shallow: true<\/code> olarak ayarlayabilirsiniz. Genellikle filtreleme gibi durumlarda <code>shallow: true<\/code> tercih edilir, ancak arama motorlar\u0131 i\u00e7in tam sayfa yenilemesi de tercih edilebilir.<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>value={searchTerm || ''}<\/code>:<\/strong> Input alan\u0131n\u0131n de\u011ferini <code>searchTerm<\/code> ile ba\u011fl\u0131yoruz. <code>searchTerm<\/code> ba\u015flang\u0131\u00e7ta <code>null<\/code> olabilir (URL'de parametre yoksa ve <code>defaultValue<\/code> ayarlanmad\u0131ysa), bu y\u00fczden bo\u015f string'e d\u00f6n\u00fc\u015ft\u00fcrmek iyi bir pratiktir.<\/li>\n<li><strong><code>onChange={(e) => setSearchTerm(e.target.value)}<\/code>:<\/strong> Kullan\u0131c\u0131 input alan\u0131na yaz\u0131 yazd\u0131\u011f\u0131nda, <code>setSearchTerm<\/code> fonksiyonunu \u00e7a\u011f\u0131rarak URL'deki <code>q<\/code> parametresini g\u00fcncelliyoruz. <code>nuqs<\/code>, bu \u00e7a\u011fr\u0131y\u0131 alg\u0131lar ve URL'yi otomatik olarak g\u00fcnceller.<\/li>\n<li><strong><code>useEffect<\/code>:<\/strong> <code>searchTerm<\/code> de\u011feri her de\u011fi\u015fti\u011finde (yani URL'deki <code>q<\/code> parametresi g\u00fcncellendi\u011finde), <code>useEffect<\/code> i\u00e7indeki kod \u00e7al\u0131\u015facakt\u0131r. Bu, URL'ye dayal\u0131 veri \u00e7ekme veya ba\u015fka yan etkileri tetiklemek i\u00e7in kullanabilece\u011finiz reaktif bir mekanizmad\u0131r.<\/li>\n<li><strong><code>setSearchTerm(null)<\/code>:<\/strong> Bir URL parametresini tamamen kald\u0131rmak istedi\u011finizde, setter fonksiyonunu <code>null<\/code> (veya <code>undefined<\/code>) ile \u00e7a\u011f\u0131rabilirsiniz. Bu, URL'den <code>?q=de\u011fer<\/code> k\u0131sm\u0131n\u0131 kald\u0131racakt\u0131r.<\/li>\n<\/ol>\n<p>Bu basit \u00f6rnekle, <code>nuqs<\/code>'un URL arama parametrelerini y\u00f6netmeyi nas\u0131l kolayla\u015ft\u0131rd\u0131\u011f\u0131n\u0131 ve tip-g\u00fcvenli\u011fini nas\u0131l sa\u011flad\u0131\u011f\u0131n\u0131 g\u00f6rm\u00fc\u015f olmal\u0131s\u0131n\u0131z. Art\u0131k manuel olarak <code>router.push()<\/code> \u00e7a\u011fr\u0131lar\u0131 yapma veya string'leri d\u00f6n\u00fc\u015ft\u00fcrme karma\u015fas\u0131ndan kurtulmu\u015f durumday\u0131z.<\/p>\n<div class=\"info-box\">Uzman \u0130pucu: <code>defaultValue<\/code> parametresi sadece URL'de ilgili parametre bulunmad\u0131\u011f\u0131nda kullan\u0131l\u0131r. E\u011fer URL'de parametre varsa, <code>defaultValue<\/code> g\u00f6z ard\u0131 edilir ve URL'deki de\u011fer kullan\u0131l\u0131r. Bu, hem ilk y\u00fcklemede hem de SSR senaryolar\u0131nda tutarl\u0131l\u0131k sa\u011flar.<\/div>\n<h2>Tip-G\u00fcvenli URL Parametreleri: nuqs ile Veri Tiplerini Korumak Nas\u0131l M\u00fcmk\u00fcn?<\/h2>\n<p>URL arama parametrelerinin en b\u00fcy\u00fck zorluklar\u0131ndan biri, taray\u0131c\u0131 taraf\u0131ndan her zaman bir string olarak ele al\u0131nmas\u0131d\u0131r. Bu durum, bir sayfa numaras\u0131 (<code>number<\/code>), bir filtre anahtar\u0131 (<code>boolean<\/code>) veya se\u00e7ili kategorilerin bir listesi (<code>string[]<\/code>) gibi farkl\u0131 veri tiplerini elle string'e d\u00f6n\u00fc\u015ft\u00fcrme ve tekrar eski haline getirme gereksinimi do\u011furur. <code>nuqs<\/code>, bu s\u00fcreci otomatikle\u015ftirerek ve tip-g\u00fcvenli\u011fini sa\u011flayarak geli\u015ftiricilerin hayat\u0131n\u0131 kolayla\u015ft\u0131r\u0131r. B\u00f6ylece, uygulaman\u0131z\u0131n daha az hataya a\u00e7\u0131k ve daha sa\u011flam olmas\u0131n\u0131 garantiler.<\/p>\n<h3>Say\u0131lar, Boolean'lar ve Diziler \u0130\u00e7in Otomatik T\u00fcr D\u00f6n\u00fc\u015f\u00fcm\u00fc<\/h3>\n<p><code>nuqs<\/code>, en yayg\u0131n kullan\u0131lan veri tipleri i\u00e7in dahili ayr\u0131\u015ft\u0131r\u0131c\u0131lar (parsers) ile gelir. Bu sayede, <code>parseAs<\/code> se\u00e7ene\u011fini kullanarak parametrenizin beklenen veri tipini belirtebilirsiniz. <code>nuqs<\/code>, URL'den okunan string de\u011feri otomatik olarak belirtilen tipe d\u00f6n\u00fc\u015ft\u00fcr\u00fcr ve ayn\u0131 \u015fekilde JavaScript'ten gelen de\u011feri de URL'ye uygun string format\u0131na \u00e7evirir.<\/p>\n<h4>Say\u0131 \u00d6rne\u011fi: Sayfa Numaras\u0131 Y\u00f6netimi<\/h4>\n<p>Bir paginasyon bile\u015feninde sayfa numaras\u0131n\u0131 URL'de tutmak olduk\u00e7a yayg\u0131nd\u0131r. <code>nuqs<\/code> ile bu, \u00e7ok basittir:<\/p>\n<pre><code>'use client';\n\nimport { useQueryState } from 'nuqs';\n\nfunction Paginasyon() {\n  const [page, setPage] = useQueryState('page', {\n    defaultValue: 1, \/\/ URL'de 'page' yoksa ba\u015flang\u0131\u00e7 1 olsun\n    parseAs: 'number', \/\/ 'page' parametresini say\u0131 olarak ayr\u0131\u015ft\u0131r\n  });\n\n  return (\n    <div style={{ padding: '15px', border: '1px dashed #bbb', borderRadius: '5px', marginTop: '20px' }}>\n      <h3>Paginasyon<\/h3>\n      <p>Mevcut Sayfa: {page}<\/p>\n      <button onClick={() => setPage((p) => Math.max(1, (p || 1) - 1))} disabled={(page || 1) <= 1}>\n        \u00d6nceki\n      <\/button>\n      <button onClick={() => setPage((p) => (p || 1) + 1)} style={{ marginLeft: '10px' }}>\n        Sonraki\n      <\/button>\n      <p style={{ fontSize: '0.9em', color: '#666' }}>\n        URL: <code>\/sayfam{page ? <code>?page=${page}<\/code> : ''}<\/code>\n      <\/p>\n    <\/div>\n  );\n}\n\nexport default Paginasyon;\n<\/pre>\n<p><\/code><\/p>\n<p>Burada, <code>parseAs: 'number'<\/code> sayesinde, URL'den gelen <code>\"2\"<\/code> string'i otomatik olarak <code>2<\/code> say\u0131s\u0131na d\u00f6n\u00fc\u015f\u00fcr. <code>setPage<\/code> ile bir say\u0131 g\u00f6nderdi\u011finizde de, <code>nuqs<\/code> bunu otomatik olarak <code>\"2\"<\/code> string'ine \u00e7evirip URL'ye ekler. Tip g\u00fcvenli\u011fi, TypeScript sayesinde <code>page<\/code> de\u011fi\u015fkeninin her zaman bir <code>number<\/code> olarak alg\u0131lanmas\u0131yla sa\u011flan\u0131r.<\/p>\n<h4>Boolean \u00d6rne\u011fi: Aktif Filtre Durumu<\/h4>\n<p>Bir filtre kutusunun a\u00e7\u0131k veya kapal\u0131 olma durumu gibi boolean de\u011ferler de <code>nuqs<\/code> ile kolayca y\u00f6netilebilir:<\/p>\n<pre><code>'use client';\n\nimport { useQueryState } from 'nuqs';\n\nfunction FilterToggle() {\n  const [showFilters, setShowFilters] = useQueryState('showFilters', {\n    defaultValue: false,\n    parseAs: 'boolean',\n  });\n\n  return (\n    <div style={{ padding: '15px', border: '1px dashed #bbb', borderRadius: '5px', marginTop: '20px' }}>\n      <h3>Filtreleri G\u00f6ster<\/h3>\n      <label>\n        <input\n          type=\"checkbox\"\n          checked={showFilters || false}\n          onChange={(e) => setShowFilters(e.target.checked)}\n        \/>\n        Filtreleri G\u00f6ster\n      <\/label>\n      <p>Filtreler \u015fu an: {showFilters ? 'A\u00e7\u0131k' : 'Kapal\u0131'}<\/p>\n      <p style={{ fontSize: '0.9em', color: '#666' }}>\n        URL: <code>\/sayfam{showFilters ? <code>?showFilters=${showFilters}<\/code> : ''}<\/code>\n      <\/p>\n    <\/div>\n  );\n}\n\nexport default FilterToggle;\n<\/pre>\n<p><\/code><\/p>\n<p><code>parseAs: 'boolean'<\/code> ile <code>\"true\"<\/code> veya <code>\"false\"<\/code> string'leri otomatik olarak JavaScript'in <code>true<\/code> veya <code>false<\/code> boolean de\u011ferlerine d\u00f6n\u00fc\u015f\u00fcr. Bu, manuel <code>\"true\" === value<\/code> kontrollerinden kurtulman\u0131z\u0131 sa\u011flar.<\/p>\n<h4>Dizi \u00d6rne\u011fi: \u00c7oklu Kategori Se\u00e7imi<\/h4>\n<p>Birden fazla kategori se\u00e7imi gibi durumlarda, de\u011ferleri bir dizi olarak URL'de tutmak isteyebilirsiniz:<\/p>\n<pre><code>'use client';\n\nimport { useQueryState } from 'nuqs';\n\nfunction CategoryFilter() {\n  \/\/ 'categories' parametresini string dizisi olarak ayr\u0131\u015ft\u0131r\n  const [selectedCategories, setSelectedCategories] = useQueryState('categories', {\n    defaultValue: [], \/\/ Ba\u015flang\u0131\u00e7ta bo\u015f dizi\n    parseAs: 'array', \/\/ veya 'array(string)'\n  });\n\n  const allCategories = ['Elektronik', 'Giyim', 'Ev', 'Kitap'];\n\n  const handleCategoryChange = (category) => {\n    setSelectedCategories((prev) => {\n      if (prev.includes(category)) {\n        return prev.filter((cat) => cat !== category);\n      }\n      return [...prev, category];\n    });\n  };\n\n  return (\n    <div style={{ padding: '15px', border: '1px dashed #bbb', borderRadius: '5px', marginTop: '20px' }}>\n      <h3>Kategori Filtresi<\/h3>\n      {allCategories.map((category) => (\n        <label key={category} style={{ marginRight: '15px' }}>\n          <input\n            type=\"checkbox\"\n            checked={selectedCategories.includes(category)}\n            onChange={() => handleCategoryChange(category)}\n          \/>\n          {category}\n        <\/label>\n      ))}\n      <p>Se\u00e7ilen Kategoriler: {selectedCategories.length > 0 ? selectedCategories.join(', ') : 'Hi\u00e7biri'}<\/p>\n      <p style={{ fontSize: '0.9em', color: '#666' }}>\n        URL: <code>\/sayfam{selectedCategories.length > 0 ? <code>?categories=${selectedCategories.join(&#039;,&#039;)}<\/code> : ''}<\/code>\n      <\/p>\n    <\/div>\n  );\n}\n\nexport default CategoryFilter;\n<\/pre>\n<p><\/code><\/p>\n<p><code>parseAs: 'array'<\/code> veya <code>parseAs: 'array(string)'<\/code> kullanarak, URL'deki virg\u00fclle ayr\u0131lm\u0131\u015f bir string'i (\u00f6rne\u011fin <code>?categories=Elektronik,Giyim<\/code>) otomatik olarak bir string dizisine d\u00f6n\u00fc\u015ft\u00fcrebilirsiniz. <code>setSelectedCategories<\/code>'e bir dizi ge\u00e7ti\u011finizde de, <code>nuqs<\/code> bunu URL i\u00e7in uygun string format\u0131na d\u00f6n\u00fc\u015ft\u00fcrecektir.<\/p>\n<h3>\u00d6zel Tip D\u00f6n\u00fc\u015ft\u00fcr\u00fcc\u00fcler ile Esneklik Kazanmak<\/h3>\n<p>Bazen <code>number<\/code>, <code>boolean<\/code> veya <code>array<\/code> gibi temel tiplerin \u00f6tesine ge\u00e7meniz gerekebilir. \u00d6rne\u011fin, bir tarih objesini, karma\u015f\u0131k bir JSON nesnesini veya belirli bir formatta string'i URL'de saklamak isteyebilirsiniz. <code>nuqs<\/code>, bu t\u00fcr senaryolar i\u00e7in <code>createParser<\/code> fonksiyonu arac\u0131l\u0131\u011f\u0131yla kendi \u00f6zel tip d\u00f6n\u00fc\u015ft\u00fcr\u00fcc\u00fclerinizi (parsers) tan\u0131mlaman\u0131za olanak tan\u0131r. Bu, k\u00fct\u00fcphanenin sundu\u011fu en g\u00fc\u00e7l\u00fc esnekliklerden biridir.<\/p>\n<h4>Tarih Objesi \u00d6rne\u011fi: Rezervasyon Tarihi<\/h4>\n<p>Bir rezervasyon sisteminde, kullan\u0131c\u0131n\u0131n se\u00e7ti\u011fi tarihi URL'de tutmak isteyebilirsiniz. JavaScript'in <code>Date<\/code> objeleri do\u011frudan URL'de saklanamaz, ancak <code>ISO 8601<\/code> gibi bir string format\u0131na d\u00f6n\u00fc\u015ft\u00fcr\u00fclebilir:<\/p>\n<pre><code>'use client';\n\nimport { useQueryState, createParser } from 'nuqs';\nimport { useState } from 'react';\n\n\/\/ \u00d6zel bir tarih parser'\u0131 olu\u015fturuyoruz\nconst dateParser = createParser({\n  parse: (value) => (value ? new Date(value) : null), \/\/ URL'den okunan string'i Date objesine d\u00f6n\u00fc\u015ft\u00fcr\n  serialize: (value) => (value instanceof Date ? value.toISOString() : null), \/\/ Date objesini ISO string'ine d\u00f6n\u00fc\u015ft\u00fcr\n});\n\nfunction DatePickerComponent() {\n  const [selectedDate, setSelectedDate] = useQueryState('date', {\n    defaultValue: null, \/\/ Ba\u015flang\u0131\u00e7ta tarih se\u00e7ili olmas\u0131n\n    parser: dateParser, \/\/ Kendi \u00f6zel parser'\u0131m\u0131z\u0131 kullan\u0131yoruz\n  });\n\n  const [inputDateString, setInputDateString] = useState(\n    selectedDate ? selectedDate.toISOString().substring(0, 10) : ''\n  );\n\n  const handleDateChange = (e) => {\n    const dateStr = e.target.value;\n    setInputDateString(dateStr);\n    if (dateStr) {\n      setSelectedDate(new Date(dateStr));\n    } else {\n      setSelectedDate(null);\n    }\n  };\n\n  return (\n    <div style={{ padding: '15px', border: '1px dashed #bbb', borderRadius: '5px', marginTop: '20px' }}>\n      <h3>Tarih Se\u00e7imi<\/h3>\n      <input\n        type=\"date\"\n        value={inputDateString}\n        onChange={handleDateChange}\n      \/>\n      <p>Se\u00e7ilen Tarih: {selectedDate ? selectedDate.toLocaleDateString() : 'Yok'}<\/p>\n      <p style={{ fontSize: '0.9em', color: '#666' }}>\n        URL: <code>\/sayfam{selectedDate ? <code>?date=${selectedDate.toISOString().substring(0, 10)}<\/code> : ''}<\/code>\n      <\/p>\n    <\/div>\n  );\n}\n\nexport default DatePickerComponent;\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>createParser<\/code> ile hem <code>parse<\/code> (URL'den okurken) hem de <code>serialize<\/code> (URL'ye yazarken) fonksiyonlar\u0131n\u0131 tan\u0131mlayarak <code>Date<\/code> objelerinin y\u00f6netimini tamamen kontrol alt\u0131na ald\u0131k. <code>nuqs<\/code>, bu parser'\u0131 kullanarak URL ile <code>Date<\/code> objesi aras\u0131nda sorunsuz bir d\u00f6n\u00fc\u015f\u00fcm sa\u011flar. Bu sayede, uygulaman\u0131zdaki tarih se\u00e7imi bile\u015fenleri URL ile tip-g\u00fcvenli bir \u015fekilde senkronize edilebilir. Bu \u00f6zellik, <code>nuqs<\/code>'un sadece temel tiplerle s\u0131n\u0131rl\u0131 kalmad\u0131\u011f\u0131n\u0131, ayn\u0131 zamanda karma\u015f\u0131k ve \u00f6zel veri tipleri i\u00e7in de g\u00fc\u00e7l\u00fc bir \u00e7\u00f6z\u00fcm sundu\u011funu g\u00f6sterir. Bu esneklik, geli\u015ftiricilere URL y\u00f6netiminde s\u0131n\u0131rs\u0131z olanaklar tan\u0131r ve uygulaman\u0131n karma\u015f\u0131kl\u0131\u011f\u0131 ne olursa olsun tutarl\u0131 bir yakla\u015f\u0131m benimsemeyi m\u00fcmk\u00fcn k\u0131lar.<\/p>\n<h2>Geli\u015fmi\u015f nuqs Kullan\u0131m\u0131: Performans, Debouncing ve \u00c7oklu Parametre Y\u00f6netimi<\/h2>\n<p><code>nuqs<\/code>, sadece temel URL parametre y\u00f6netimi sunmakla kalmaz, ayn\u0131 zamanda daha karma\u015f\u0131k senaryolar ve performans optimizasyonlar\u0131 i\u00e7in geli\u015fmi\u015f \u00f6zellikler de sa\u011flar. Bu b\u00f6l\u00fcmde, kullan\u0131c\u0131 deneyimini ve uygulaman\u0131z\u0131n performans\u0131n\u0131 art\u0131racak debouncing mekanizmas\u0131n\u0131, birden fazla URL parametresini e\u015f zamanl\u0131 olarak y\u00f6netme yetene\u011fini ve <code>shallow routing<\/code> ile <code>SSR<\/code> entegrasyonu gibi konular\u0131 ele alaca\u011f\u0131z.<\/p>\n<h3>Debouncing ile Performans\u0131 Art\u0131rmak<\/h3>\n<p>Arama kutular\u0131 veya ger\u00e7ek zamanl\u0131 filtreler gibi alanlarda kullan\u0131c\u0131 girdisi \u00e7ok h\u0131zl\u0131 de\u011fi\u015febilir. Kullan\u0131c\u0131n\u0131n her tu\u015f vuru\u015funda URL'yi an\u0131nda g\u00fcncellemek, taray\u0131c\u0131 ge\u00e7mi\u015finde \u00e7ok say\u0131da giri\u015f olu\u015fturabilir ve gereksiz yeniden render'lara neden olarak performans\u0131 d\u00fc\u015f\u00fcrebilir. <code>nuqs<\/code>, bu sorunu \u00e7\u00f6zmek i\u00e7in <code>debounce<\/code> se\u00e7ene\u011fi sunar. Bu se\u00e7enek, URL g\u00fcncellemesini belirli bir s\u00fcre geciktirerek, kullan\u0131c\u0131n\u0131n duraklamas\u0131n\u0131 bekler ve sadece son de\u011feri URL'ye yans\u0131t\u0131r.<\/p>\n<pre><code>'use client';\n\nimport { useQueryState } from 'nuqs';\nimport { useState } from 'react';\n\nfunction DebouncedSearchInput() {\n  \/\/ 'q' parametresini 500ms gecikmeli olarak g\u00fcncelle\n  const [searchTerm, setSearchTerm] = useQueryState('q', {\n    defaultValue: '',\n    debounce: 500, \/\/ 500 milisaniye gecikme\n  });\n\n  const [localInput, setLocalInput] = useState(searchTerm || '');\n\n  const handleInputChange = (e) => {\n    setLocalInput(e.target.value);\n    setSearchTerm(e.target.value); \/\/ Bu \u00e7a\u011fr\u0131 debounced olacak\n  };\n\n  return (\n    <div style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px', marginTop: '20px' }}>\n      <h3>Debounced Arama Kutusu<\/h3>\n      <input\n        type=\"text\"\n        value={localInput}\n        onChange={handleInputChange}\n        placeholder=\"Arama terimi (debounced)\"\n        style={{ padding: '8px', borderRadius: '4px', border: '1px solid #ccc', width: '300px' }}\n      \/>\n      <p>URL'deki arama terimi (debounced): <strong>{searchTerm}<\/strong><\/p>\n      <p>Lokal girdi: <strong>{localInput}<\/strong><\/p>\n      <p style={{ fontSize: '0.9em', color: '#666' }}>\n        URL: <code>\/debounced-sayfam{searchTerm ? <code>?q=${searchTerm}<\/code> : ''}<\/code>\n      <\/p>\n    <\/div>\n  );\n}\n\nexport default DebouncedSearchInput;\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnekte, kullan\u0131c\u0131 <code>input<\/code> alan\u0131na yazmaya ba\u015flad\u0131\u011f\u0131nda, <code>setSearchTerm<\/code> \u00e7a\u011fr\u0131s\u0131 an\u0131nda URL'yi g\u00fcncellemez. Bunun yerine, 500 milisaniye bekler. E\u011fer bu s\u00fcre i\u00e7inde ba\u015fka bir karakter yaz\u0131l\u0131rsa, \u00f6nceki gecikmeli g\u00fcncelleme iptal edilir ve yeni bir 500ms'lik gecikme ba\u015flar. Bu, kullan\u0131c\u0131n\u0131n yazmay\u0131 bitirmesini bekleyerek URL'yi ve dolay\u0131s\u0131yla tetiklenecek verileri yaln\u0131zca gerekti\u011finde g\u00fcncellemek i\u00e7in harika bir yoldur. <code>localInput<\/code> state'i ise kullan\u0131c\u0131n\u0131n anl\u0131k girdisini UI'da an\u0131nda g\u00f6stermek i\u00e7in kullan\u0131l\u0131rken, <code>searchTerm<\/code> URL ile debounced bir \u015fekilde senkronize kal\u0131r.<\/p>\n<h3>Birden Fazla Parametreyi E\u015f Zamanl\u0131 Y\u00f6netmek<\/h3>\n<p>Bir \u00fcr\u00fcn listeleme sayfas\u0131nda hem kategori, hem fiyat aral\u0131\u011f\u0131, hem de s\u0131ralama gibi birden fazla parametreyi ayn\u0131 anda y\u00f6netmeniz gerekebilir. <code>useQueryState<\/code> tek bir parametre i\u00e7in harika olsa da, bir\u00e7ok parametrenin e\u015f zamanl\u0131 ve koordineli y\u00f6netimi i\u00e7in <code>nuqs<\/code>, <code>useQueryStates<\/code> hook'unu sunar. Bu hook, tek bir \u00e7a\u011fr\u0131 ile birden fazla URL parametresini g\u00fcncellemeyi ve bunlar\u0131n tip g\u00fcvenli\u011fini sa\u011flamay\u0131 m\u00fcmk\u00fcn k\u0131lar.<\/p>\n<pre><code>'use client';\n\nimport { useQueryStates } from 'nuqs';\nimport { useEffect } from 'react';\n\nfunction AdvancedFilterComponent() {\n  const [{ search, category, sort, priceMin, priceMax }, setQueryStates] = useQueryStates({\n    search: { parseAs: 'string', defaultValue: '' },\n    category: { parseAs: 'string', defaultValue: 'all' },\n    sort: { parseAs: 'string', defaultValue: 'newest' },\n    priceMin: { parseAs: 'number', defaultValue: 0 },\n    priceMax: { parseAs: 'number', defaultValue: 1000 },\n  });\n\n  useEffect(() => {\n    console.log('Filtreler de\u011fi\u015fti:', { search, category, sort, priceMin, priceMax });\n    \/\/ Bu noktada filtrelenmi\u015f verileri \u00e7ekebilirsiniz.\n  }, [search, category, sort, priceMin, priceMax]);\n\n  return (\n    <div style={{ padding: '20px', border: '1px solid #4CAF50', borderRadius: '8px', marginTop: '20px' }}>\n      <h3>Geli\u015fmi\u015f Filtre Y\u00f6netimi<\/h3>\n      <div style={{ marginBottom: '10px' }}>\n        <label>\n          Arama:\n          <input\n            type=\"text\"\n            value={search || ''}\n            onChange={(e) => setQueryStates({ search: e.target.value })}\n            style={{ marginLeft: '5px' }}\n          \/>\n        <\/label>\n      <\/div>\n      <div style={{ marginBottom: '10px' }}>\n        <label>\n          Kategori:\n          <select\n            value={category || 'all'}\n            onChange={(e) => setQueryStates({ category: e.target.value })}\n            style={{ marginLeft: '5px' }}\n          >\n            <option value=\"all\">T\u00fcm\u00fc<\/option>\n            <option value=\"electronics\">Elektronik<\/option>\n            <option value=\"clothing\">Giyim<\/option>\n          <\/select>\n        <\/label>\n      <\/div>\n      <div style={{ marginBottom: '10px' }}>\n        <label>\n          S\u0131rala:\n          <select\n            value={sort || 'newest'}\n            onChange={(e) => setQueryStates({ sort: e.target.value })}\n            style={{ marginLeft: '5px' }}\n          >\n            <option value=\"newest\">En Yeni<\/option>\n            <option value=\"price_asc\">Fiyat (Artan)<\/option>\n            <option value=\"price_desc\">Fiyat (Azalan)<\/option>\n          <\/select>\n        <\/label>\n      <\/div>\n      <div style={{ marginBottom: '10px' }}>\n        <label>\n          Fiyat Aral\u0131\u011f\u0131:\n          <input\n            type=\"number\"\n            value={priceMin || 0}\n            onChange={(e) => setQueryStates({ priceMin: Number(e.target.value) })}\n            style={{ marginLeft: '5px', width: '80px' }}\n          \/>\n          -\n          <input\n            type=\"number\"\n            value={priceMax || 1000}\n            onChange={(e) => setQueryStates({ priceMax: Number(e.target.value) })}\n            style={{ marginLeft: '5px', width: '80px' }}\n          \/>\n        <\/label>\n      <\/div>\n      <button onClick={() => setQueryStates({ search: null, category: null, sort: null, priceMin: null, priceMax: null })} style={{ marginTop: '10px' }}>\n        Filtreleri Temizle\n      <\/button>\n      <p style={{ fontSize: '0.9em', color: '#666', marginTop: '10px' }}>\n        Mevcut URL Filtreleri: <pre><code>{JSON.stringify({ search, category, sort, priceMin, priceMax }, null, 2)}<\/pre>\n<p><\/code>\n      <\/p>\n<\/p><\/div>\n<p>  );<br \/>\n}<\/p>\n<p>export default AdvancedFilterComponent;<br \/>\n<\/code><\/p>\n<p><code>useQueryStates<\/code> hook'u, bir nesne al\u0131r ve bu nesnenin her anahtar\u0131, y\u00f6netmek istedi\u011finiz bir URL parametresini temsil eder. Her parametre i\u00e7in <code>parseAs<\/code> ve <code>defaultValue<\/code> gibi se\u00e7enekleri belirtebilirsiniz. <code>setQueryStates<\/code> fonksiyonu ise, bir nesne alarak birden fazla parametreyi tek bir i\u015flemde g\u00fcnceller. Bu, taray\u0131c\u0131 ge\u00e7mi\u015fine yaln\u0131zca tek bir giri\u015f eklenmesini sa\u011flar ve UI g\u00fcncellemelerini optimize eder.<\/p>\n<div class=\"info-box\">Uzman \u0130pucu: \u00c7oklu parametre g\u00fcncellemelerinde <code>setQueryStates<\/code> kullanmak, ayr\u0131 ayr\u0131 g\u00fcncellemeler yapmaktan daha verimlidir, \u00e7\u00fcnk\u00fc bu i\u015flem taray\u0131c\u0131 ge\u00e7mi\u015fine tek bir giri\u015f yapar ve gereksiz render'lar\u0131 azalt\u0131r. Ayr\u0131ca <code>null<\/code> veya <code>undefined<\/code> de\u011ferleri atayarak parametreleri URL'den kald\u0131rabilirsiniz.<\/div>\n<h3>Shallow Routing ve Server-Side Rendered (SSR) Parametreler<\/h3>\n<p><strong>Shallow Routing (<code>shallow: true<\/code>):<\/strong> Next.js'te <code>shallow routing<\/code>, sayfa yenilemesi olmadan URL'yi g\u00fcncelleme yetene\u011fidir. <code>nuqs<\/code>, <code>useQueryState<\/code> veya <code>useQueryStates<\/code> hook'lar\u0131na <code>shallow: true<\/code> se\u00e7ene\u011fini ekleyerek bu davran\u0131\u015f\u0131 kolayca etkinle\u015ftirmenizi sa\u011flar. Bu, \u00f6zellikle client-side etkile\u015fimlerle (\u00f6rne\u011fin bir filtreyi a\u00e7\u0131p kapatmak) URL'yi g\u00fcncellemek ve sayfa state'ini korumak istedi\u011finiz durumlarda kullan\u0131\u015fl\u0131d\u0131r. \u00d6rne\u011fin, bir modal a\u00e7\u0131ld\u0131\u011f\u0131nda URL'ye <code>?modal=true<\/code> eklemek ve sayfay\u0131 yenilememek i\u00e7in idealdir.<\/p>\n<pre><code>'use client';\n\nimport { useQueryState } from 'nuqs';\n\nfunction ModalComponent() {\n  const [isModalOpen, setIsModalOpen] = useQueryState('modal', {\n    defaultValue: false,\n    parseAs: 'boolean',\n    shallow: true, \/\/ Sayfa yenilemesi yapma\n  });\n\n  return (\n    <div style={{ padding: '15px', border: '1px dotted #888', borderRadius: '5px', marginTop: '20px' }}>\n      <h3>Modal Durumu<\/h3>\n      <button onClick={() => setIsModalOpen((prev) => !prev)}>\n        Modal\u0131 {isModalOpen ? 'Kapat' : 'A\u00e7'}\n      <\/button>\n      {isModalOpen && (\n        <div style={{ border: '1px solid #555', padding: '10px', marginTop: '10px', background: '#f9f9f9' }}>\n          Bu bir modal i\u00e7eri\u011fidir.\n        <\/div>\n      )}\n      <p style={{ fontSize: '0.9em', color: '#666' }}>\n        URL: <code>\/modal-sayfam{isModalOpen ? <code>?modal=${isModalOpen}<\/code> : ''}<\/code> (Shallow routing ile g\u00fcncellenir)\n      <\/p>\n    <\/div>\n  );\n}\n\nexport default ModalComponent;\n<\/pre>\n<p><\/code><\/p>\n<p><strong>Server-Side Rendered (SSR) Parametreler:<\/strong> <code>nuqs<\/code>, Next.js'in server komponentleriyle de uyumludur. Server komponentlerinde do\u011frudan <code>useQueryState<\/code> kullanamasan\u0131z da (\u00e7\u00fcnk\u00fc React hook'lar\u0131 sadece client komponentlerde \u00e7al\u0131\u015f\u0131r), URL'deki parametrelere eri\u015fmek i\u00e7in <code>Next.js<\/code>'in <code>searchParams<\/code> prop'unu kullanabilir ve bunu <code>nuqs<\/code>'un <code>defaultValue<\/code> veya <code>initialValues<\/code> (<code>useQueryStates<\/code> i\u00e7in) olarak besleyebilirsiniz. Bu, sayfan\u0131n ilk y\u00fcklenmesinde ve sunucu taraf\u0131nda olu\u015fturulurken do\u011fru URL state'ine sahip olmas\u0131n\u0131 sa\u011flar, bu da SEO ve ilk y\u00fckleme performans\u0131 i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<pre><code>\/\/ app\/page.tsx (Server Component)\nimport SearchComponent from '..\/components\/SearchComponent'; \/\/ \u00d6nceki SearchComponent'i import ediyoruz\nimport Paginasyon from '..\/components\/Paginasyon';\nimport FilterToggle from '..\/components\/FilterToggle';\nimport CategoryFilter from '..\/components\/CategoryFilter';\nimport DatePickerComponent from '..\/components\/DatePickerComponent';\nimport DebouncedSearchInput from '..\/components\/DebouncedSearchInput';\nimport AdvancedFilterComponent from '..\/components\/AdvancedFilterComponent';\nimport ModalComponent from '..\/components\/ModalComponent';\n\ninterface HomePageProps {\n  searchParams: { [key: string]: string | string[] | undefined };\n}\n\nexport default function HomePage({ searchParams }: HomePageProps) {\n  \/\/ searchParams'\u0131 do\u011frudan nuqs hook'lar\u0131na beslemesek de,\n  \/\/ bu, initial state'i ayarlamak i\u00e7in kullan\u0131labilir.\n  \/\/ nuqs, client taraf\u0131nda kendi ba\u015f\u0131na searchParams'\u0131 okuyacakt\u0131r.\n  \/\/ Ancak server komponentleri render edilirken,\n  \/\/ nuqs client component i\u00e7inde \u00e7al\u0131\u015fmaya ba\u015flayana kadar URL'deki parametreler kullan\u0131labilir durumda olacakt\u0131r.\n\n  const initialSearchTerm = searchParams.q as string || '';\n  const initialPage = Number(searchParams.page) || 1;\n  const initialShowFilters = searchParams.showFilters === 'true';\n\n  return (\n    <div style={{ maxWidth: '900px', margin: '40px auto', padding: '20px', fontFamily: 'Arial, sans-serif' }}>\n      <h1>nuqs ile Next.js URL Parametre Y\u00f6netimi<\/h1>\n      <p>Bu sayfadaki bile\u015fenler, URL'deki arama parametreleriyle etkile\u015fim kurar ve onlar\u0131 tip-g\u00fcvenli bir \u015fekilde y\u00f6netir.<\/p>\n\n      <h2>\u00d6rnek Uygulamalar<\/h2>\n      <SearchComponent \/>\n      <Paginasyon \/>\n      <FilterToggle \/>\n      <CategoryFilter \/>\n      <DatePickerComponent \/>\n      <DebouncedSearchInput \/>\n      <AdvancedFilterComponent \/>\n      <ModalComponent \/>\n\n      <h3 style={{ marginTop: '30px' }}>Sunucu Taraf\u0131ndan Okunan \u0130lk Parametreler<\/h3>\n      <ul>\n        <li>Arama Terimi (q): <strong>{initialSearchTerm || 'Yok'}<\/strong><\/li>\n        <li>Sayfa Numaras\u0131 (page): <strong>{initialPage}<\/strong><\/li>\n        <li>Filtreler A\u00e7\u0131k M\u0131? (showFilters): <strong>{initialShowFilters.toString()}<\/strong><\/li>\n      <\/ul>\n\n      <p style={{ marginTop: '20px', fontSize: '0.9em', color: '#888' }}>\n        Not: Yukar\u0131daki \"Sunucu Taraf\u0131ndan Okunan \u0130lk Parametreler\" k\u0131sm\u0131, Next.js'in <code>searchParams<\/code> prop'u arac\u0131l\u0131\u011f\u0131yla sunucu taraf\u0131nda do\u011frudan URL parametrelerine nas\u0131l eri\u015filebilece\u011fini g\u00f6sterir. Client komponentleri (\u00f6rne\u011fin SearchComponent) ise kendi i\u00e7lerinde nuqs kullanarak bu parametreleri reaktif bir \u015fekilde y\u00f6netir.\n      <\/p>\n    <\/div>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu geli\u015fmi\u015f \u00f6zellikler sayesinde <code>nuqs<\/code>, Next.js uygulamalar\u0131n\u0131zda URL y\u00f6netimini sadece kolayla\u015ft\u0131rmakla kalmaz, ayn\u0131 zamanda daha sa\u011flam, performansl\u0131 ve kullan\u0131c\u0131 dostu hale getirir. Uygulaman\u0131z\u0131n \u00f6l\u00e7e\u011fi ve karma\u015f\u0131kl\u0131\u011f\u0131 ne olursa olsun, <code>nuqs<\/code> size g\u00fc\u00e7l\u00fc ve esnek bir ara\u00e7 seti sunar.<\/p>\n<h2>Vaka Analizi: E-ticaret Sitesi \u0130\u00e7in Geli\u015fmi\u015f Filtreleme Sistemi<\/h2>\n<p>\u015eimdiye kadar <code>nuqs<\/code>'un temel ve geli\u015fmi\u015f \u00f6zelliklerini g\u00f6rd\u00fck. \u015eimdi bu bilgileri, ger\u00e7ek d\u00fcnyadan bir senaryo \u00fczerinde, bir e-ticaret sitesi i\u00e7in geli\u015fmi\u015f bir \u00fcr\u00fcn filtreleme sistemi geli\u015ftirirken nas\u0131l uygulayaca\u011f\u0131m\u0131za bakal\u0131m. Bu vaka analizi, <code>nuqs<\/code>'un karma\u015f\u0131k bir kullan\u0131c\u0131 aray\u00fcz\u00fcnde ne kadar etkili ve verimli olabilece\u011fini net bir \u015fekilde ortaya koyacakt\u0131r.<\/p>\n<h3>Senaryo: Dinamik \u00dcr\u00fcn Listeleme ve Filtreleme<\/h3>\n<p>Hayal edin ki bir e-ticaret platformu geli\u015ftiriyorsunuz. \u00dcr\u00fcn listeleme sayfas\u0131nda kullan\u0131c\u0131lar:<\/p>\n<ul>\n<li>Belirli <strong>kategorileri<\/strong> se\u00e7ebilir (\u00e7oklu se\u00e7im).<\/li>\n<li>Bir <strong>fiyat aral\u0131\u011f\u0131<\/strong> belirleyebilirler.<\/li>\n<li>\u0130stedikleri <strong>markalar\u0131<\/strong> filtreleyebilirler (\u00e7oklu se\u00e7im).<\/li>\n<li>\u00dcr\u00fcnleri <strong>fiyata g\u00f6re<\/strong> (artan\/azalan) veya <strong>yenili\u011fe g\u00f6re<\/strong> s\u0131ralayabilirler.<\/li>\n<li>Bir <strong>arama terimi<\/strong> girebilirler.<\/li>\n<li>Listede <strong>sayfalar<\/strong> aras\u0131nda gezinebilirler.<\/li>\n<\/ul>\n<p>T\u00fcm bu filtreleme ve s\u0131ralama se\u00e7eneklerinin, kullan\u0131c\u0131n\u0131n sayfay\u0131 yenilemeden etkile\u015fim kurabilmesi ve URL'de do\u011fru bir \u015fekilde temsil edilmesi gerekmektedir. B\u00f6ylece kullan\u0131c\u0131lar filtrelenmi\u015f bir \u00fcr\u00fcn listesinin URL'sini payla\u015fabilir veya yer i\u015faretleyebilir.<\/p>\n<h3>Mevcut Durum Sorunu: Geleneksel Yakla\u015f\u0131m\u0131n Yetersizlikleri<\/h3>\n<p>Geleneksel olarak, b\u00f6yle bir sistemi Next.js'in standart <code>useSearchParams<\/code> hook'u veya manuel state y\u00f6netimi ile kurmaya \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131zda, h\u0131zla karma\u015f\u0131kla\u015fan bir kod y\u0131\u011f\u0131n\u0131 ile kar\u015f\u0131la\u015f\u0131r\u0131z:<\/p>\n<ol>\n<li><strong>Tip-G\u00fcvenli\u011fi Eksikli\u011fi:<\/strong> Her parametre string olarak gelir. Kategori listesini virg\u00fclle ayr\u0131lm\u0131\u015f string'den diziye \u00e7evirme, fiyat aral\u0131\u011f\u0131n\u0131 say\u0131ya d\u00f6n\u00fc\u015ft\u00fcrme gibi i\u015flemlerin her yerde elle yap\u0131lmas\u0131 gerekir. Bu, TypeScript'in sa\u011flad\u0131\u011f\u0131 faydalar\u0131 azalt\u0131r.<\/li>\n<li><strong>Boilerplate Kod:<\/strong> Her bir filtre i\u00e7in ayr\u0131 ayr\u0131 <code>useState<\/code> tan\u0131mlama, URL'den okuma, de\u011feri ayr\u0131\u015ft\u0131rma, bir <code>onChange<\/code> veya <code>onClick<\/code> olay\u0131nda <code>router.push()<\/code> veya <code>router.replace()<\/code> ile URL'yi g\u00fcncelleme i\u015flemleri tekrarlan\u0131r. Bu, kod tekrar\u0131na yol a\u00e7ar.<\/li>\n<li><strong>Reaktivite ve Senkronizasyon Zorluklar\u0131:<\/strong> Uygulama state'i ile URL aras\u0131ndaki senkronizasyonu manuel olarak sa\u011flamak zordur. \u00d6zellikle bir filtre de\u011fi\u015fti\u011finde di\u011ferlerinin de g\u00fcncellenmesi gerekti\u011finde, bu s\u00fcre\u00e7 hataya a\u00e7\u0131k hale gelir.<\/li>\n<li><strong>Performans Endi\u015feleri:<\/strong> Her filtre de\u011fi\u015fikli\u011finde <code>router.push()<\/code> \u00e7a\u011f\u0131rmak, taray\u0131c\u0131 ge\u00e7mi\u015fine \u00e7ok say\u0131da giri\u015f ekleyebilir ve performans\u0131 olumsuz etkileyebilir. \u00d6zellikle arama terimi gibi s\u0131k de\u011fi\u015fen parametrelerde bu durum daha da belirginle\u015fir.<\/li>\n<\/ol>\n<h3>nuqs \u00c7\u00f6z\u00fcm\u00fc: Temiz ve G\u00fc\u00e7l\u00fc Y\u00f6netim<\/h3>\n<p><code>nuqs<\/code>, bu karma\u015f\u0131k senaryoyu y\u00f6netmek i\u00e7in ideal bir ara\u00e7t\u0131r. <code>useQueryStates<\/code> hook'u ve tip-g\u00fcvenli ayr\u0131\u015ft\u0131r\u0131c\u0131lar\u0131 sayesinde, t\u00fcm filtreleme parametrelerini tek bir merkezden, temiz ve verimli bir \u015fekilde y\u00f6netebiliriz.<\/p>\n<h4><code>nuqs<\/code> ile Filtreleme Sistemi Uygulamas\u0131<\/h4>\n<p>Bir ana \u00fcr\u00fcn listeleme bile\u015fenimiz oldu\u011funu ve bu bile\u015fenin i\u00e7inde \u00e7e\u015fitli filtre bile\u015fenlerini bar\u0131nd\u0131rd\u0131\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnelim. Her filtre bile\u015feni, kendi parametresini <code>nuqs<\/code> arac\u0131l\u0131\u011f\u0131yla URL ile senkronize edecektir. Ana sayfam\u0131z\u0131n (<code>app\/products\/page.tsx<\/code>) yap\u0131s\u0131 a\u015fa\u011f\u0131daki gibi olabilir:<\/p>\n<pre><code>\/\/ app\/products\/page.tsx\n'use client'; \/\/ Ana sayfa bile\u015fenimiz client taraf\u0131nda \u00e7al\u0131\u015fmal\u0131\n\nimport { useQueryStates } from 'nuqs';\nimport { useEffect } from 'react';\n\n\/\/ Filtre bile\u015fenlerinin import'lar\u0131 (a\u015fa\u011f\u0131da detayland\u0131r\u0131lacak)\nimport CategoryFilter from '..\/..\/components\/filters\/CategoryFilter';\nimport PriceRangeFilter from '..\/..\/components\/filters\/PriceRangeFilter';\nimport BrandFilter from '..\/..\/components\/filters\/BrandFilter';\nimport SortFilter from '..\/..\/components\/filters\/SortFilter';\nimport SearchInput from '..\/..\/components\/filters\/SearchInput';\nimport PaginationControls from '..\/..\/components\/filters\/PaginationControls';\n\ninterface Product {\n  id: number;\n  name: string;\n  category: string;\n  price: number;\n  brand: string;\n  \/\/ Di\u011fer \u00fcr\u00fcn \u00f6zellikleri\n}\n\n\/\/ Mock \u00fcr\u00fcn verisi\nconst allProducts: Product[] = [\n  { id: 1, name: 'Ak\u0131ll\u0131 Telefon X', category: 'Elektronik', price: 12000, brand: 'Marka A' },\n  { id: 2, name: 'Kablosuz Kulakl\u0131k Y', category: 'Elektronik', price: 1500, brand: 'Marka B' },\n  { id: 3, name: 'Diz\u00fcst\u00fc Bilgisayar Z', category: 'Elektronik', price: 25000, brand: 'Marka A' },\n  { id: 4, name: 'T-Shirt M', category: 'Giyim', price: 250, brand: 'Marka C' },\n  { id: 5, name: 'Kot Pantolon N', category: 'Giyim', price: 500, brand: 'Marka D' },\n  { id: 6, name: 'Roman Kitab\u0131 A', category: 'Kitap', price: 75, brand: 'Yay\u0131nevi E' },\n  { id: 7, name: 'Tablet P', category: 'Elektronik', price: 8000, brand: 'Marka B' },\n  { id: 8, name: 'Ak\u0131ll\u0131 Saat Q', category: 'Elektronik', price: 3000, brand: 'Marka A' },\n];\n\nconst ITEMS_PER_PAGE = 3;\n\nexport default function ProductListingPage() {\n  const [{ categories, priceMin, priceMax, brands, sort, search, page }, setAllFilters] = useQueryStates({\n    categories: { parseAs: 'array(string)', defaultValue: [] },\n    priceMin: { parseAs: 'number', defaultValue: 0 },\n    priceMax: { parseAs: 'number', defaultValue: 50000 },\n    brands: { parseAs: 'array(string)', defaultValue: [] },\n    sort: { parseAs: 'string', defaultValue: 'newest' },\n    search: { parseAs: 'string', defaultValue: '', debounce: 300 }, \/\/ Arama i\u00e7in debouncing\n    page: { parseAs: 'number', defaultValue: 1 },\n  });\n\n  \/\/ Filtrelenmi\u015f \u00fcr\u00fcnleri hesaplama (ger\u00e7ekte bu sunucuda veya bir API \u00e7a\u011fr\u0131s\u0131yla yap\u0131l\u0131r)\n  const filteredProducts = allProducts.filter(product => {\n    \/\/ Kategori filtrelemesi\n    const categoryMatch = categories.length === 0 || categories.includes(product.category);\n\n    \/\/ Fiyat aral\u0131\u011f\u0131 filtrelemesi\n    const priceMatch = product.price >= (priceMin || 0) && product.price <= (priceMax || 50000);\n\n    \/\/ Marka filtrelemesi\n    const brandMatch = brands.length === 0 || brands.includes(product.brand);\n\n    \/\/ Arama terimi filtrelemesi\n    const searchTermMatch = (search === '' || product.name.toLowerCase().includes((search || '').toLowerCase()));\n\n    return categoryMatch &#038;&#038; priceMatch &#038;&#038; brandMatch &#038;&#038; searchTermMatch;\n  }).sort((a, b) => {\n    \/\/ S\u0131ralama\n    if (sort === 'price_asc') return a.price - b.price;\n    if (sort === 'price_desc') return b.price - a.price;\n    return 0; \/\/ 'newest' veya varsay\u0131lan s\u0131ralama\n  });\n\n  \/\/ Paginasyon i\u00e7in \u00fcr\u00fcnleri b\u00f6lme\n  const totalPages = Math.ceil(filteredProducts.length \/ ITEMS_PER_PAGE);\n  const startIndex = ((page || 1) - 1) * ITEMS_PER_PAGE;\n  const paginatedProducts = filteredProducts.slice(startIndex, startIndex + ITEMS_PER_PAGE);\n\n  useEffect(() => {\n    \/\/ Filtreler veya sayfa de\u011fi\u015fti\u011finde logla veya veri \u00e7ek\n    console.log('URL filtreleri g\u00fcncellendi:', { categories, priceMin, priceMax, brands, sort, search, page });\n    \/\/ Ger\u00e7ek bir uygulamada, burada sunucudan yeni filtrelenmi\u015f \u00fcr\u00fcnleri \u00e7ekmek i\u00e7in bir API \u00e7a\u011fr\u0131s\u0131 yapard\u0131n\u0131z.\n  }, [categories, priceMin, priceMax, brands, sort, search, page]);\n\n  return (\n    <div style={{ display: 'flex', gap: '20px', padding: '20px', maxWidth: '1200px', margin: '0 auto' }}>\n      <aside style={{ flex: '0 0 250px', padding: '15px', borderRight: '1px solid #eee' }}>\n        <h2>Filtreler<\/h2>\n        <SearchInput currentSearch={search || ''} setSearch={(s) => setAllFilters({ search: s })} \/>\n        <CategoryFilter currentCategories={categories || []} setCategories={(c) => setAllFilters({ categories: c })} allCategories={['Elektronik', 'Giyim', 'Kitap']} \/>\n        <PriceRangeFilter currentMin={priceMin || 0} currentMax={priceMax || 50000} setPriceRange={(min, max) => setAllFilters({ priceMin: min, priceMax: max })} \/>\n        <BrandFilter currentBrands={brands || []} setBrands={(b) => setAllFilters({ brands: b })} allBrands={['Marka A', 'Marka B', 'Marka C', 'Marka D', 'Yay\u0131nevi E']} \/>\n        <SortFilter currentSort={sort || 'newest'} setSort={(s) => setAllFilters({ sort: s })} \/>\n        <button\n          onClick={() => setAllFilters({\n            categories: null, priceMin: null, priceMax: null, brands: null, sort: null, search: null, page: 1\n          })}\n          style={{ padding: '10px 15px', background: '#dc3545', color: 'white', border: 'none', borderRadius: '5px', cursor: 'pointer', marginTop: '20px' }}\n        >\n          T\u00fcm Filtreleri Temizle\n        <\/button>\n      <\/aside>\n\n      <main style={{ flex: 1 }}>\n        <h2>\u00dcr\u00fcnler ({filteredProducts.length} adet)<\/h2>\n        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '20px' }}>\n          {paginatedProducts.length > 0 ? (\n            paginatedProducts.map(product => (\n              <div key={product.id} style={{ border: '1px solid #ddd', padding: '15px', borderRadius: '8px', boxShadow: '0 2px 5px rgba(0,0,0,0.1)' }}>\n                <h3>{product.name}<\/h3>\n                <p><strong>Kategori:<\/strong> {product.category}<\/p>\n                <p><strong>Marka:<\/strong> {product.brand}<\/p>\n                <p><strong>Fiyat:<\/strong> {product.price} TL<\/p>\n              <\/div>\n            ))\n          ) : (\n            <p>Se\u00e7ilen filtrelere uygun \u00fcr\u00fcn bulunamad\u0131.<\/p>\n          )}\n        <\/div>\n        <PaginationControls currentPage={page || 1} totalPages={totalPages} setPage={(p) => setAllFilters({ page: p })} \/>\n      <\/main>\n    <\/div>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki <code>ProductListingPage<\/code> bile\u015feni, <code>useQueryStates<\/code> kullanarak t\u00fcm filtre parametrelerini tek bir noktada tan\u0131mlar. Her bir filtre i\u00e7in <code>parseAs<\/code> ve <code>defaultValue<\/code> ayarlar\u0131, tip g\u00fcvenli\u011fini ve ba\u015flang\u0131\u00e7 durumlar\u0131n\u0131 garanti eder. <code>SearchInput<\/code> i\u00e7in <code>debounce<\/code> se\u00e7ene\u011fi kullan\u0131larak gereksiz URL g\u00fcncellemeleri engellenir. \u015eimdi, bu ana bile\u015fenin kulland\u0131\u011f\u0131 alt filtre bile\u015fenlerinin nas\u0131l g\u00f6r\u00fcnebilece\u011fine dair baz\u0131 \u00f6rnekler:<\/p>\n<pre><code>\/\/ components\/filters\/CategoryFilter.tsx\n'use client';\nimport React from 'react';\n\ninterface CategoryFilterProps {\n  currentCategories: string[];\n  setCategories: (categories: string[]) => void;\n  allCategories: string[];\n}\n\nconst CategoryFilter: React.FC<CategoryFilterProps> = ({ currentCategories, setCategories, allCategories }) => {\n  const toggleCategory = (category: string) => {\n    setCategories(\n      currentCategories.includes(category)\n        ? currentCategories.filter((c) => c !== category)\n        : [...currentCategories, category]\n    );\n  };\n\n  return (\n    <div style={{ marginBottom: '20px' }}>\n      <h4>Kategoriler<\/h4>\n      {allCategories.map((cat) => (\n        <label key={cat} style={{ display: 'block', marginBottom: '5px' }}>\n          <input\n            type=\"checkbox\"\n            checked={currentCategories.includes(cat)}\n            onChange={() => toggleCategory(cat)}\n            style={{ marginRight: '5px' }}\n          \/>\n          {cat}\n        <\/label>\n      ))}\n    <\/div>\n  );\n};\n\nexport default CategoryFilter;\n<\/pre>\n<p><\/code><\/p>\n<pre><code>\/\/ components\/filters\/PriceRangeFilter.tsx\n'use client';\nimport React from 'react';\n\ninterface PriceRangeFilterProps {\n  currentMin: number;\n  currentMax: number;\n  setPriceRange: (min: number, max: number) => void;\n}\n\nconst PriceRangeFilter: React.FC<PriceRangeFilterProps> = ({ currentMin, currentMax, setPriceRange }) => {\n  const handleMinChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    setPriceRange(Number(e.target.value), currentMax);\n  };\n\n  const handleMaxChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    setPriceRange(currentMin, Number(e.target.value));\n  };\n\n  return (\n    <div style={{ marginBottom: '20px' }}>\n      <h4>Fiyat Aral\u0131\u011f\u0131<\/h4>\n      <input\n        type=\"number\"\n        value={currentMin}\n        onChange={handleMinChange}\n        style={{ width: '80px', marginRight: '10px', padding: '5px' }}\n      \/>\n      -\n      <input\n        type=\"number\"\n        value={currentMax}\n        onChange={handleMaxChange}\n        style={{ width: '80px', marginLeft: '10px', padding: '5px' }}\n      \/>\n    <\/div>\n  );\n};\n\nexport default PriceRangeFilter;\n<\/pre>\n<p><\/code><\/p>\n<p>(Di\u011fer filtre bile\u015fenleri de benzer \u015fekilde, ana <code>ProductListingPage<\/code>'den ald\u0131\u011f\u0131 prop'larla <code>setAllFilters<\/code> fonksiyonunu \u00e7a\u011f\u0131rarak URL'deki ilgili parametreleri g\u00fcncelleyecektir.)<\/p>\n<h4>Vaka Analizinin Faydalar\u0131<\/h4>\n<ul>\n<li><strong>Merkezi Y\u00f6netim:<\/strong> T\u00fcm filtre parametreleri <code>useQueryStates<\/code> ile ana bile\u015fende merkezi olarak tan\u0131mlan\u0131r. Bu, kodun daha d\u00fczenli ve anla\u015f\u0131l\u0131r olmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Tip G\u00fcvenli\u011fi:<\/strong> TypeScript ve <code>nuqs<\/code>'un <code>parseAs<\/code> \u00f6zelli\u011fi sayesinde, <code>categories<\/code> her zaman bir <code>string[]<\/code>, <code>priceMin<\/code>\/<code>priceMax<\/code> her zaman bir <code>number<\/code> olarak ele al\u0131n\u0131r. Bu, geli\u015ftirme s\u0131ras\u0131nda potansiyel hatalar\u0131 ortadan kald\u0131r\u0131r.<\/li>\n<li><strong>Geli\u015fmi\u015f Kullan\u0131c\u0131 Deneyimi:<\/strong> <code>shallow routing<\/code> (varsay\u0131lan olarak <code>useQueryStates<\/code> taraf\u0131ndan yap\u0131l\u0131r) sayesinde, kullan\u0131c\u0131lar filtreleri de\u011fi\u015ftirdik\u00e7e sayfa yenilenmez. <code>debounce<\/code> \u00f6zelli\u011fi ile arama terimi giri\u015finde gereksiz g\u00fcncellemeler engellenir. Kullan\u0131c\u0131lar URL'yi payla\u015fabilir ve ayn\u0131 filtreli sayfay\u0131 do\u011frudan a\u00e7abilir.<\/li>\n<li><strong>Daha Az Boilerplate:<\/strong> Manuel URL ayr\u0131\u015ft\u0131rma, serile\u015ftirme ve <code>router.push()<\/code> \u00e7a\u011fr\u0131lar\u0131ndan kurtulunur. Bu, geli\u015ftirme s\u00fcresini k\u0131salt\u0131r ve kodun bak\u0131m\u0131n\u0131 kolayla\u015ft\u0131r\u0131r.<\/li>\n<\/ul>\n<p>Bu vaka analizi, <code>nuqs<\/code>'un Next.js'te karma\u015f\u0131k URL parametre y\u00f6netimi gerektiren durumlar i\u00e7in ne kadar g\u00fc\u00e7l\u00fc ve pratik bir \u00e7\u00f6z\u00fcm sundu\u011funu a\u00e7\u0131k\u00e7a g\u00f6stermektedir. Geli\u015ftiriciler, k\u00fct\u00fcphanenin sundu\u011fu soyutlama sayesinde i\u015f mant\u0131\u011f\u0131na daha fazla odaklanabilir ve URL y\u00f6netimi karma\u015fas\u0131yla u\u011fra\u015fmaktan kurtulabilirler.<\/p>\n<h2>Sonu\u00e7: nuqs ile Temiz ve G\u00fc\u00e7l\u00fc URL Y\u00f6netiminin Gelece\u011fi<\/h2>\n<p>Next.js uygulamalar\u0131nda URL arama parametrelerini y\u00f6netmek, geleneksel yakla\u015f\u0131mlarla genellikle karma\u015f\u0131k, hataya a\u00e7\u0131k ve geli\u015ftirici deneyimini olumsuz etkileyen bir s\u00fcre\u00e7 olmu\u015ftur. Ancak <code>nuqs<\/code> k\u00fct\u00fcphanesi, bu alanda adeta bir devrim niteli\u011finde bir \u00e7\u00f6z\u00fcm sunarak, URL'leri uygulaman\u0131z\u0131n tip-g\u00fcvenli, reaktif ve y\u00f6netilebilir bir par\u00e7as\u0131 haline getiriyor. Bu makale boyunca, <code>nuqs<\/code>'un kurulumundan temel ve ileri d\u00fczey kullan\u0131mlar\u0131na, tip g\u00fcvenli\u011finden performans optimizasyonlar\u0131na ve ger\u00e7ek d\u00fcnya senaryolar\u0131na kadar bir\u00e7ok y\u00f6n\u00fcn\u00fc detayl\u0131ca inceledik.<\/p>\n<p><code>nuqs<\/code>'un sundu\u011fu <code>useQueryState<\/code> ve <code>useQueryStates<\/code> gibi hook'lar, React'\u0131n <code>useState<\/code> modelinden esinlenerek geli\u015ftiricilere tan\u0131d\u0131k ve sezgisel bir API sunar. Otomatik tip \u00e7\u0131kar\u0131m\u0131 ve \u00f6zel ayr\u0131\u015ft\u0131r\u0131c\u0131lar sayesinde, URL'den okunan verilerin do\u011fru tiplerde olmas\u0131n\u0131 garanti alt\u0131na al\u0131rken, gereksiz manuel d\u00f6n\u00fc\u015ft\u00fcrme i\u015flemlerinden kurtulursunuz. Debouncing ve shallow routing gibi \u00f6zellikler ise, hem uygulaman\u0131z\u0131n performans\u0131n\u0131 art\u0131r\u0131r hem de kullan\u0131c\u0131 deneyimini zenginle\u015ftirir. \u00d6zellikle e-ticaret sitelerindeki geli\u015fmi\u015f filtreleme sistemleri gibi karma\u015f\u0131k senaryolarda <code>nuqs<\/code>, kod tekrar\u0131n\u0131 azaltarak, okunabilirli\u011fi art\u0131rarak ve hata olas\u0131l\u0131\u011f\u0131n\u0131 d\u00fc\u015f\u00fcrerek geli\u015ftiricilere b\u00fcy\u00fck kolayl\u0131klar sa\u011flar.<\/p>\n<p>Next.js ekosisteminde, <code>nuqs<\/code> URL parametre y\u00f6netimi i\u00e7in tercih edilen modern bir standart olma potansiyeli ta\u015f\u0131maktad\u0131r. Hem App Router hem de Pages Router ile uyumlu olmas\u0131, g\u00fc\u00e7l\u00fc TypeScript deste\u011fi ve minimal yap\u0131land\u0131rma gereksinimi, onu her \u00f6l\u00e7ekten Next.js projesi i\u00e7in ideal bir se\u00e7im haline getiriyor. Sonu\u00e7 olarak, <code>nuqs<\/code> sadece bir k\u00fct\u00fcphane de\u011fil, ayn\u0131 zamanda URL y\u00f6netimini d\u00fc\u015f\u00fcnme ve uygulama bi\u00e7imimizde bir ilerlemedir. Uygulamalar\u0131n\u0131zda temiz, g\u00fc\u00e7l\u00fc ve kullan\u0131c\u0131 dostu URL'ler olu\u015fturmak istiyorsan\u0131z, <code>nuqs<\/code> listenizin ba\u015f\u0131nda yer almal\u0131d\u0131r.<\/p>\n<h2>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h2>\n<h3>nuqs sadece App Router ile mi \u00e7al\u0131\u015f\u0131r?<\/h3>\n<p>Hay\u0131r, <code>nuqs<\/code> hem Next.js'in yeni App Router yap\u0131s\u0131 hem de Pages Router yap\u0131s\u0131 ile tamamen uyumludur. App Router'da client component'lerinizde <code>'use client'<\/code> direktifi ile, Pages Router'da ise standart React component'lerinizde kullanabilirsiniz. Server component'lerde do\u011frudan hook kullanamasan\u0131z da, <code>searchParams<\/code> prop'unu kullanarak ilk de\u011ferleri besleyebilir ve client component'lerinizde <code>nuqs<\/code>'u kullanmaya devam edebilirsiniz.<\/p>\n<h3>nuqs kullanmak performans\u0131 etkiler mi?<\/h3>\n<p>Hay\u0131r, do\u011fru kullan\u0131ld\u0131\u011f\u0131nda <code>nuqs<\/code> performans\u0131 olumsuz etkilemez. Aksine, manuel URL y\u00f6netimi ve <code>router.push()<\/code> \u00e7a\u011fr\u0131lar\u0131na k\u0131yasla daha optimize ve kontrol edilebilir g\u00fcncellemeler sunar. \u00d6zellikle <code>debounce<\/code> se\u00e7ene\u011fi ile gereksiz ve s\u0131k URL g\u00fcncellemelerini engelleyebilir, <code>shallow: true<\/code> ile de tam sayfa yenilemeleri yerine daha h\u0131zl\u0131 client-side navigasyonlar sa\u011flayabilirsiniz. <code>nuqs<\/code>, taray\u0131c\u0131 ge\u00e7mi\u015fine yap\u0131lan giri\u015fleri de m\u00fcmk\u00fcn oldu\u011funca optimize eder.<\/p>\n<h3>URL'deki bir parametreyi tamamen kald\u0131rmak i\u00e7in ne yapmal\u0131y\u0131m?<\/h3>\n<p>Bir URL parametresini tamamen kald\u0131rmak i\u00e7in ilgili <code>setQueryState<\/code> fonksiyonunu <code>null<\/code> veya <code>undefined<\/code> de\u011feriyle \u00e7a\u011f\u0131rman\u0131z yeterlidir. \u00d6rne\u011fin, <code>setSearchTerm(null)<\/code> \u00e7a\u011fr\u0131s\u0131, URL'deki <code>q<\/code> parametresini kald\u0131racakt\u0131r. E\u011fer <code>useQueryStates<\/code> kullan\u0131yorsan\u0131z, parametre nesnesinde kald\u0131rmak istedi\u011finiz anahtara <code>null<\/code> veya <code>undefined<\/code> de\u011feri atayabilirsiniz.<\/p>\n<h3>nuqs, Next.js'in kendi <code>useSearchParams<\/code>'\u0131ndan ne kadar farkl\u0131?<\/h3>\n<p>Next.js'in yerle\u015fik <code>useSearchParams<\/code> hook'u, URL'deki arama parametrelerini yaln\u0131zca okumak i\u00e7in tasarlanm\u0131\u015ft\u0131r ve bir de\u011fer atamak veya de\u011fi\u015ftirmek i\u00e7in do\u011frudan bir setter fonksiyonu sunmaz. Parametreleri de\u011fi\u015ftirmek i\u00e7in <code>useRouter<\/code> ile programatik navigasyon yapman\u0131z gerekir. <code>nuqs<\/code> ise hem okuma hem de yazma i\u015flevselli\u011fi sunar; t\u0131pk\u0131 <code>useState<\/code> gibi bir <code>[value, setter]<\/code> \u00e7ifti sa\u011flar. Ayr\u0131ca, tip g\u00fcvenli\u011fi, otomatik ayr\u0131\u015ft\u0131rma\/serile\u015ftirme, debouncing, custom parser'lar ve birden fazla parametreyi tek seferde y\u00f6netme gibi ileri d\u00fczey \u00f6zelliklerle geli\u015ftirici deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde zenginle\u015ftirir.<\/p>\n<h3>Karma\u015f\u0131k JSON objelerini URL'de saklayabilir miyim?<\/h3>\n<p>Evet, <code>nuqs<\/code>'un <code>createParser<\/code> fonksiyonunu kullanarak \u00f6zel bir JSON parser'\u0131 tan\u0131mlayabilirsiniz. Bu parser, JavaScript objelerini <code>JSON.stringify()<\/code> ile bir string'e d\u00f6n\u00fc\u015ft\u00fcr\u00fcp URL'ye ekler ve URL'den okurken <code>JSON.parse()<\/code> ile geri objeye \u00e7evirir. Ancak, URL'lerin boyutu s\u0131n\u0131rl\u0131 oldu\u011fundan \u00e7ok b\u00fcy\u00fck veya s\u0131k de\u011fi\u015fen JSON objeleri i\u00e7in URL yerine localStorage veya sunucu taraf\u0131 bir depolama y\u00f6ntemi kullanmak daha iyi bir \u00e7\u00f6z\u00fcm olabilir.<\/p>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1469],"tags":[],"class_list":{"0":"post-36114","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-nextjs","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim<\/title>\n<meta name=\"description\" content=\"Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131 kayna\u011f\u0131 olabilen bir konudur. Genellikle string olarak gelen bu parametreleri elle ayr\u0131\u015ft\u0131rmak, do\u011fru tiplere d\u00f6n\u00fc\u015ft\u00fcrmek ve uygulama state&#039;i ile senkronize etmek, hem zaman al\u0131c\u0131 hem de hata yapmaya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Neyse ki, nuqs gibi modern k\u00fct\u00fcphaneler bu zorluklar\u0131 a\u015fmak i\u00e7in g\u00fc\u00e7l\u00fc ve zarif bir \u00e7\u00f6z\u00fcm sunuyor. Bu makalede, nuqs&#039;un Next.js projelerinizde URL arama parametrelerini nas\u0131l tip-g\u00fcvenli, reaktif ve zahmetsiz bir \u015fekilde y\u00f6netmenizi sa\u011flad\u0131\u011f\u0131n\u0131 derinlemesine inceleyece\u011fiz.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim\" \/>\n<meta property=\"og:description\" content=\"Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131 kayna\u011f\u0131 olabilen bir konudur. Genellikle string olarak gelen bu parametreleri elle ayr\u0131\u015ft\u0131rmak, do\u011fru tiplere d\u00f6n\u00fc\u015ft\u00fcrmek ve uygulama state&#039;i ile senkronize etmek, hem zaman al\u0131c\u0131 hem de hata yapmaya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Neyse ki, nuqs gibi modern k\u00fct\u00fcphaneler bu zorluklar\u0131 a\u015fmak i\u00e7in g\u00fc\u00e7l\u00fc ve zarif bir \u00e7\u00f6z\u00fcm sunuyor. Bu makalede, nuqs&#039;un Next.js projelerinizde URL arama parametrelerini nas\u0131l tip-g\u00fcvenli, reaktif ve zahmetsiz bir \u015fekilde y\u00f6netmenizi sa\u011flad\u0131\u011f\u0131n\u0131 derinlemesine inceleyece\u011fiz.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-08T10:31:48+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"32 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim\",\"datePublished\":\"2025-12-08T10:31:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/\"},\"wordCount\":4719,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"NextJS\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/\",\"name\":\"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-08T10:31:48+00:00\",\"description\":\"Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131 kayna\u011f\u0131 olabilen bir konudur. Genellikle string olarak gelen bu parametreleri elle ayr\u0131\u015ft\u0131rmak, do\u011fru tiplere d\u00f6n\u00fc\u015ft\u00fcrmek ve uygulama state'i ile senkronize etmek, hem zaman al\u0131c\u0131 hem de hata yapmaya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Neyse ki, nuqs gibi modern k\u00fct\u00fcphaneler bu zorluklar\u0131 a\u015fmak i\u00e7in g\u00fc\u00e7l\u00fc ve zarif bir \u00e7\u00f6z\u00fcm sunuyor. Bu makalede, nuqs'un Next.js projelerinizde URL arama parametrelerini nas\u0131l tip-g\u00fcvenli, reaktif ve zahmetsiz bir \u015fekilde y\u00f6netmenizi sa\u011flad\u0131\u011f\u0131n\u0131 derinlemesine inceleyece\u011fiz.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim","description":"Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131 kayna\u011f\u0131 olabilen bir konudur. Genellikle string olarak gelen bu parametreleri elle ayr\u0131\u015ft\u0131rmak, do\u011fru tiplere d\u00f6n\u00fc\u015ft\u00fcrmek ve uygulama state'i ile senkronize etmek, hem zaman al\u0131c\u0131 hem de hata yapmaya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Neyse ki, nuqs gibi modern k\u00fct\u00fcphaneler bu zorluklar\u0131 a\u015fmak i\u00e7in g\u00fc\u00e7l\u00fc ve zarif bir \u00e7\u00f6z\u00fcm sunuyor. Bu makalede, nuqs'un Next.js projelerinizde URL arama parametrelerini nas\u0131l tip-g\u00fcvenli, reaktif ve zahmetsiz bir \u015fekilde y\u00f6netmenizi sa\u011flad\u0131\u011f\u0131n\u0131 derinlemesine inceleyece\u011fiz.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/","og_locale":"tr_TR","og_type":"article","og_title":"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim","og_description":"Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131 kayna\u011f\u0131 olabilen bir konudur. Genellikle string olarak gelen bu parametreleri elle ayr\u0131\u015ft\u0131rmak, do\u011fru tiplere d\u00f6n\u00fc\u015ft\u00fcrmek ve uygulama state'i ile senkronize etmek, hem zaman al\u0131c\u0131 hem de hata yapmaya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Neyse ki, nuqs gibi modern k\u00fct\u00fcphaneler bu zorluklar\u0131 a\u015fmak i\u00e7in g\u00fc\u00e7l\u00fc ve zarif bir \u00e7\u00f6z\u00fcm sunuyor. Bu makalede, nuqs'un Next.js projelerinizde URL arama parametrelerini nas\u0131l tip-g\u00fcvenli, reaktif ve zahmetsiz bir \u015fekilde y\u00f6netmenizi sa\u011flad\u0131\u011f\u0131n\u0131 derinlemesine inceleyece\u011fiz.","og_url":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-08T10:31:48+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"32 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim","datePublished":"2025-12-08T10:31:48+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/"},"wordCount":4719,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["NextJS"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/","url":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/","name":"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-08T10:31:48+00:00","description":"Next.js uygulamalar\u0131nda URL arama parametreleri (search params) y\u00f6netimi, karma\u015f\u0131kla\u015fmaya e\u011filimli ve \u00e7o\u011fu zaman geli\u015ftiriciler i\u00e7in bir ba\u015f a\u011fr\u0131s\u0131 kayna\u011f\u0131 olabilen bir konudur. Genellikle string olarak gelen bu parametreleri elle ayr\u0131\u015ft\u0131rmak, do\u011fru tiplere d\u00f6n\u00fc\u015ft\u00fcrmek ve uygulama state'i ile senkronize etmek, hem zaman al\u0131c\u0131 hem de hata yapmaya a\u00e7\u0131k bir s\u00fcre\u00e7tir. Neyse ki, nuqs gibi modern k\u00fct\u00fcphaneler bu zorluklar\u0131 a\u015fmak i\u00e7in g\u00fc\u00e7l\u00fc ve zarif bir \u00e7\u00f6z\u00fcm sunuyor. Bu makalede, nuqs'un Next.js projelerinizde URL arama parametrelerini nas\u0131l tip-g\u00fcvenli, reaktif ve zahmetsiz bir \u015fekilde y\u00f6netmenizi sa\u011flad\u0131\u011f\u0131n\u0131 derinlemesine inceleyece\u011fiz.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-url-arama-parametreleri-nuqs-ile-tip-guvenli-ve-reaktif-yonetim\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Next.js URL Arama Parametreleri: nuqs ile Tip-G\u00fcvenli ve Reaktif Y\u00f6netim"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=36114"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36114\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=36114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=36114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=36114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}