- Konu sahibi
- #1
Next.js dinamik rota nasıl çalışır?
Next.js’te dinamik rota, URL içindeki değişken bir parçayı köşeli parantezli klasör veya dosya adıyla tanımlamaktır. Örneğin
app/products/[id]/page.js dosyası, /products/42 adresini eşleştirir; 42 değeri params Promise’i çözüldüğünde id alanından okunur. Böylece her ürün için ayrı dosya oluşturmadan aynı sayfa bileşeni farklı kimliklerle çalışır.App Router’da temel yapı
Çalışan bir App Router projesinde kök layout dosyasının mevcut olduğunu varsayalım. Aşağıdaki dosya yapısı kurgu ürünlerle rota eşleşmesini gösterir:
Kod:
app/
products/
[id]/
page.js
page.js içeriği:
Kod:
import { notFound } from "next/navigation";
const products = new Map([
["42", { name: "Mekanik Klavye", stock: true }],
["73", { name: "USB Mikrofon", stock: false }]
]);
export default async function ProductPage({ params }) {
const { id } = await params;
const product = products.get(id);
if (!product) {
notFound();
}
return (
<main>
<h1>{product.name}</h1>
<p>Ürün kodu: {id}</p>
<p>{product.stock ? "Stokta" : "Stokta yok"}</p>
</main>
);
}
Proje kökünde
npm run dev çalıştırıp /products/42 adresini açtığınızda “Mekanik Klavye”, ürün kodu olarak “42” ve stok durumu görüntülenir. /products/73 farklı veriyi, /products/999 ise en yakın not-found arayüzünü tetikler. İsterseniz app/products/not-found.js dosyasında kendi bulunamadı görünümünüzü tanımlayın.Bu örnekte
[id] klasör adı dinamik segmenttir. Next.js URL’deki değeri metin olarak verir; veritabanı sorgusu yapıyorsanız sayısal kimlik bekleyen sisteme göndermeden önce doğrulamanız veya dönüştürmeniz gerekir. Gerçek uygulamada products nesnesinin yerine veritabanı ya da API çağrısı konur.params ile arama parametresi aynı değildir
/products/42?tab=reviews adresinde 42 değeri rota parametresidir ve await params sonrası id alanından alınır. tab=reviews ise arama parametresidir; rota klasörünün eşleşmesini değiştirmez. Bu iki veri türünü birbirine karıştırmak, özellikle filtre ve detay sayfalarında hatalı sonuçlara yol açar.Hangi dinamik rota biçimini seçmeli?
Klasör adındaki parantez sayısı ve üç nokta kullanımı, URL’nin kaç segment kabul edeceğini belirler:
| Yapı | Örnek adres | Gelen değer |
|---|---|---|
[id] | /products/42 | Tek değer: id |
[...parts] | /docs/js/setup | Bir veya daha fazla segmentten oluşan dizi |
[[...parts]] | /docs | Sıfır veya daha fazla segment; kök adres de eşleşebilir |
Tek bir kaynak kimliği için
[id] kullanın. Kategori, dosya yolu veya iç içe sayfa yapısı için catch-all biçimlerini tercih edin. Bir rotayı gereğinden fazla esnek tanımlamak, hatalı URL’lerin de sayfaya ulaşmasına neden olabilir.Uygularken izlenecek kararlar
- URL’de değişecek parçayı belirleyin. Ürün kimliği için
products/[id], makale adresi içinblog/[slug]gibi açık bir segment adı seçin. - Dinamik klasörü
appaltında oluşturup içinepage.jsveyapage.tsxkoyun. - Bileşen içinde
paramsdeğerini alın ve bu değerle veri kaynağını sorgulayın. Kullanıcı girdisini sorguya doğrudan eklemek yerine veri türünü ve beklenen biçimi kontrol edin. - Kayıt bulunamadığında uygun bir 404 davranışı oluşturun. Örnekteki gibi notFound() kullanın; yalnızca “bulunamadı” metni döndürmek aynı davranışı kurmaz.
- Gerçek bir URL ve olmayan bir URL ile test edin. İlki doğru kaydı, ikincisi beklenen hata veya bulunamadı durumunu vermelidir.
Sayfa açılmıyorsa neyi kontrol etmeli?
Önce dosya adının tam olarak
[id] biçiminde olduğunu ve page.js dosyasının bu klasörün içinde bulunduğunu kontrol edin. URL’deki sabit parçalar klasörlerle aynı sırada olmalıdır; app/products/[id]/page.js için doğru biçim /products/deger adresidir. params.id boşsa genellikle yanlış klasör seviyesi, hatalı segment adı veya başka bir rotayla çakışma vardır.Güncel App Router API’sinde params bir Promise’dir; async sunucu sayfasında await ile çözülür. Eski örneklerdeki doğrudan params.id erişimini körlemesine taşımayın. Ayrıca dynamic segment yalnız URL eşleşmesini tanımlar; sayfanın mutlaka her istekte sunucuda yeniden üretileceğini söylemez.
Sık sorulan sorular
Dinamik rotada aynı sayfaya birden fazla veri nasıl gönderilir?
URL’de birden fazla bağımsız parça varsa
shop/[category]/[id] gibi birden fazla dinamik segment kullanabilirsiniz. Sunucu sayfasında const { category, id } = await params ile iki değeri ayrı alın.