Kleydev karakteri
KleydevMuhammet Ali KılıçBilgisayar Mühendisi & Full-Stack Geliştirici
Ana SayfaYazılarGönderilerProjelerTeknolojiYer İmleriİletişim

Çevrimiçi
X (Twitter)GitHubLinkedInInstagramYouTube
Kleydev karakteri
KleydevMuhammet Ali KılıçBilgisayar Mühendisi & Full-Stack Geliştirici
Ana SayfaYazılarGönderilerProjelerTeknolojiYer İmleriİletişim

ÇevrimiçiX (Twitter)GitHubLinkedInInstagramYouTube

Yazılar

28 Mayıs 2026

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/
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 → BookmarksView

Server 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.

Kural: useState, useEffect, onClick, useRouter gibi tarayıcı API'leri gerektiren her şey için 'use client' direktifi zorunlu. Geri kalan her şey sunucuda kalmalı.

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.

components/projects/ProjectsView.tsx
"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.

next.config.ts
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.

components/layout/PortfolioLayout.tsx
<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