Next.js App Router: Pratik Rehber
App Router mimarisi, Server Components, veri çekme kalıpları ve client sınırını doğru çizmenin yolları.
Next.js 14 ile birlikte App Router artık production-ready kabul ediliyor. Pages Router'dan geçerken veya sıfırdan proje kurarken karşılaşılan en büyük zorluk, sunucu ve istemci sınırını doğru belirlemek. Bu yazıda bu portfolio sitesini kurarken edindiğim pratikleri özetledim.
Dosya tabanlı routing
App Router'da her klasör bir route segmentine karşılık gelir. layout.tsx ortak kabuğu taşır ve alt route'lar değişse bile yeniden render edilmez. page.tsx ise o route'un içeriğini döndürür.
app/
├── layout.tsx # Root layout — font, metadata, shell
├── page.tsx # / → Ana sayfa
├── writing/
│ └── page.tsx # /writing → WritingView
├── projects/
│ └── page.tsx # /projects → ProjectsView
└── bookmarks/
└── page.tsx # /bookmarks → BookmarksViewServer Components varsayılan
App Router'da bileşenler sunucuda render edilir. Bu sayede veritabanı sorguları, API istekleri ve hassas ortam değişkenleri client bundle'ına girmez. Performans açısından büyük kazanım: ilk yükleme payloadı küçülür, SEO iyileşir.
Client sınırını küçük tut
En yaygın hata tüm sayfayı client component yapmak. Bunun yerine etkileşimli parçayı izole et. Örneğin bir sayfa listesi statik olabilir ama arama kutusu client gerektirir — sadece SearchBar'ı 'use client' yap.
"use client";
// Sadece filtre/sıralama state'i burada
// Veri prop olarak gelir veya useEffect ile çekilir
export function ProjectsView() {
const [filter, setFilter] = useState("all");
// ...
}Veri çekme: rewrites ile proxy
Backend bir Express.js API ise next.config.ts'e rewrite ekleyerek /api/* isteklerini backend'e yönlendirebilirsin. Bu sayede tarayıcıdan yapılan fetch istekleri Network sekmesinde görünür ve CORS sorunları olmaz.
const nextConfig: NextConfig = {
async rewrites() {
return [
{
source: "/api/:path*",
destination: `${backendUrl}/api/:path*`,
},
];
},
};Layout overflow zinciri
Sidebar + içerik düzeninde bağımsız scroll için overflow zincirini viewport'tan iç alana kadar bilinçli kurmak gerekiyor. min-h-0 eksik olduğunda flex child büyür, taşar ve sayfa kayar.
<div className="flex h-dvh overflow-hidden">
<Sidebar /> {/* sabit, kendi scroll'u */}
<main className="flex min-h-0 flex-1 flex-col overflow-hidden">
{children} {/* sayfa bazında overflow-y-auto */}
</main>
</div>- h-dvh — gerçek viewport yüksekliği (mobile adres çubuğunu hesaba katar)
- overflow-hidden on root — sayfa taşmasını engeller
- min-h-0 on main — flex child'ın shrink edebilmesini sağlar
- overflow-y-auto on page — sadece içerik alanı kayar