02 / 12
Routing ve layout
Sayfa, layout, dinamik segment, route group ve Link ile gezinme.
Klasör = Adres
App Router dosya tabanlıdır. Her klasör URL'de bir segment, klasördeki page.tsx o adresin sayfasıdır.1
app/
├── layout.tsx # tüm sayfaları sarar
├── page.tsx # /
└── products/
├── layout.tsx # /products ve altını sarar
├── page.tsx # /products
└── [slug]/
└── page.tsx # /products/canvas-sneakerLayout: Gezinmede Kalan Arayüz
Layout, alt sayfaları children olarak sarar. Kullanıcı /products/a'dan /products/b'ye geçtiğinde ortak layout yeniden render edilmez; state'i ve scroll'u korunur, yalnızca sayfa değişir.1
// app/products/layout.tsx
export default function ProductsLayout({ children }: LayoutProps<"/products">) {
return (
<section>
<aside>Kategoriler</aside>
{children}
</section>
);
}LayoutProps ve PageProps import etmeden kullandığınız global tiplerdir. Next.js onları next dev, next build ya da next typegen sırasında klasörlerinizden üretir; params tipini elle yazmazsınız.1
Layout yeniden render edilmediği için iki sınırı vardır:2
searchParamsalamaz; değer bayatlardı. URL parametresini sayfada ya da bir Client Component'teuseSearchParamsile okuyun.Aktif menü için
pathnamealamaz. LinkleriusePathnamekullanan küçük bir Client Component'e taşıyın.
Warning
Oturum kontrolünü layout'a koymayın. Layout gezinmede tekrar çalışmadığı için her alt sayfayı korumaz. Kontrolü veriye yakın yapın; Next.js'te auth dersi bunu ayrıntılı anlatıyor.
Dinamik Segment
Köşeli parantezli klasör veriden üretilen sayfalar içindir:3
| Klasör | Eşleşen adres |
|---|---|
[slug] | /products/canvas-sneaker |
[...slug] | /shop/shoes, /shop/shoes/sneakers |
[[...slug]] | /docs, /docs/setup, /docs/setup/node |
// app/products/[slug]/page.tsx
export default async function ProductPage({ params }: PageProps<"/products/[slug]">) {
const { slug } = await params;
const product = await getProduct(slug);
return <h1>{product?.name}</h1>;
}params ve searchParams bir Promise'tir; await etmeden kullanamazsınız. Eski tutorial'larda params.slug diye doğrudan okunur; Next.js 15'ten beri bu değişti.4
Tip
Bu ve sonraki birkaç dersteki örnekler kısa olsun diye params'ı sayfanın en üstünde okuyor. Partial Prefetching açıkken Next.js geliştirmede bunu bir uyarıyla işaretler; çünkü bir rotaya giden bütün linkler tek bir kabuğu paylaşır. Gerçek projede params'ı <Suspense> içindeki bir child'da okuyun. Nedeni Navigasyon ve prefetch dersinde.5
searchParams: Sayfada mı, İstemcide mi
| İhtiyaç | Kullanın |
|---|---|
| Filtre ve sayfalamayla sunucudan veri çekmek | Sayfanın searchParams prop'u |
| Zaten yüklenmiş bir listeyi istemcide süzmek | useSearchParams hook'u |
searchParams okumak sayfanın o kısmını istek anına bağlar. Cache Components ile bunu bir <Suspense> içinde yapmanız gerekir; nedenini Cache ve render modeli dersinde göreceksiniz.1
Route Group ve Birden Fazla Layout
Parantezli klasör URL'ye eklenmez ama kendi layout'una sahip olabilir. Mağaza ve pazarlama sayfalarına farklı üst menü vermek için:6
app/
├── (marketing)/
│ ├── layout.tsx # pazarlama menüsü
│ └── about/page.tsx # /about
└── (shop)/
├── layout.tsx # mağaza menüsü ve sepet
└── cart/page.tsx # /cartKök app/layout.tsx'i silip her gruba kendi <html>'li layout'unu verirseniz birden fazla kök layout kurarsınız. Gruplar arasında geçişte sayfa tamamen yeniden yüklenir.6
Link ile Gezinme
<Link>, <a>'yı genişletir. Görünür linklerin hedefini arka planda prefetch eder ve tıklamada sayfayı yenilemeden geçiş yapar; ortak layout'lar yerinde kalır.7
import Link from "next/link";
<Link href={`/products/${product.slug}`}>{product.name}</Link>;Kodla yönlendirme için useRouter kullanılır. Doğru import yeri next/navigation'dır. next/router eski Pages Router'a aittir ve App Router'da çalışmaz.8 AI araçları bu ikisini sık karıştırır.
Arama gibi URL'ye parametre yazan formlar için next/form var. <form> gibi davranır ama gönderimi istemci tarafı gezinmeye çevirir ve JavaScript yüklenmeden de çalışır:9
import Form from "next/form";
<Form action="/products">
<input name="q" aria-label="Ürün ara" />
<button>Ara</button>
</Form>;Tip
next.config.ts'te typedRoutes: true açarsanız <Link href="/prodcts"> gibi yazım hataları tip hatası olur.10
İleri Kalıplar
İki kalıp belirli arayüzler içindir, her projede gerekmez:1112
| Kalıp | Klasör | Örnek |
|---|---|---|
| Parallel route | @cart/ | Aynı layout'ta bağımsız yüklenen iki bölüm |
| Intercepting route | (.)photo/[id] | Listeden açılan fotoğrafı modal olarak göstermek, linki paylaşınca tam sayfa |
Kendin Dene
app/products/[slug]/page.tsx'teparams'ıawaitetmedenparams.slugdiye okuyun. TypeScript ne diyor?products/layout.tsx'e bir sayaç butonu (Client Component) ekleyin. İki ürün arasında gezinin; sayaç sıfırlanıyor mu?Aktif menü linkini
usePathnameile işaretleyen birNavLinkyazın.typedRoutes'u açıp var olmayan bir adrese link verin.
Detaylı Öğrenmek İçin
Resmi doküman: "Layouts and Pages" ve "Linking and Navigating" sayfaları; prefetch, streaming ve istemci tarafı geçişin birlikte nasıl çalıştığını anlatır.17
Resmi doküman:
layout.jsreferansının "Caveats" bölümü; layout'un nedensearchParamsvepathnamealmadığını örneklerle gösterir.2Resmi doküman: Next.js Learn kursunun layout ve navigasyon bölümleri.13
Kaynaklar
Sayfa, iç içe layout, dinamik segment, `searchParams` ve `PageProps`/`LayoutProps` yardımcıları.
Layout'un yeniden render edilmemesi, `searchParams` ve `pathname` sınırları, aktif link örneği.
`[slug]`, catch-all ve optional catch-all segmentler.
`params`, `searchParams`, `cookies` ve `headers`'ın async olması.
URL verisinin paylaşılan App Shell'e girmemesi ve `params`'ı `<Suspense>` içine taşımak.
URL'yi etkilemeden gruplama, gruba özel layout ve birden fazla kök layout.
Prefetch, streaming, istemci tarafı geçiş ve yavaş geçişin nedenleri.
`next/navigation`'dan import, `push`, `replace`, `refresh` ve Pages Router farkı.
URL parametresi yazan formlar, istemci tarafı gezinme ve progressive enhancement.
`typedRoutes` ile tip güvenli linkler.
`@slot` klasörleri ve `default.tsx`.
`(.)`, `(..)` kalıpları ve modal örneği.
Kursun layout ve sayfa bölümü.
Last updated: October 21, 2026
