Next.js 16 App Router: Server Components Öğreticisi
Bu rehberde ne öğreneceksiniz?
Bu yazı bir haber özeti değil; adım adım uygulayabileceğiniz bir öğretici makale (tutorial) formatındadır. Her bölümün sonunda pratik çıkarımlar ve üretim ortamında karşılaşacağınız senaryolar yer alır.
- Server ve Client Component sınırını doğru çizmek
- Async Server Component ile veri getirmeyi öğrenmek
- Streaming, Suspense ve loading.tsx kullanmak
- Cache ve revalidation stratejisi seçmek
Ön koşullar
Rehberi verimli takip etmek için aşağıdaki bilgilere aşina olmanız önerilir. Eksik hissettiğiniz konularda ilgili bölümde ek kaynak ipuçları bulacaksınız.
- React temelleri (props, state, hooks)
- HTTP ve SSR kavramına aşinalık
- TypeScript strict mod
Güncellik ve teknoloji yığını
Makale 2026 itibarıyla güncellenmiştir. Örnekler ve API referansları şu yığınla uyumludur: Next.js 16.2+, React 19.2+, next-intl 4.x. Eski sürüm dokümantasyonu ile karıştırmamak için major versiyon farklarını özellikle belirttik.
Framework sürümleri hızla değişir; kalıcı olan prensipler (güvenlik, katman ayrımı, ölçüm) bu rehberin omurgasını oluşturur.
Bölüm 1: Mental model
Server Component sunucuda çalışır, istemciye HTML (+ minimal RSC payload) gider. Client Component JavaScript bundle'a girer. Varsayılan: sunucu.
Interaktivite (onClick, useState) → Client. Veritabanı, secret, ağır kütüphane → Server. Bu ayrım performans değil, mimari disiplindir.
- Etkileşim var mı?
- Browser API gerekli mi?
- Hassas veri işleniyor mu?
- Hepsi hayır → Server Component
Bölüm 2: Veri getirme
Pages Router'daki getServerSideProps yerine async page component kullanılır. Veri kodu UI ile yan yana ama data katmanına delegate edilmelidir.
Adım adım uygulama
Aşağıdaki sırayı takip edin. Her adımı tamamlamadan bir sonrakine geçmeyin; özellikle güvenlik ve veri katmanı adımları atlanmamalıdır.
lib/data/blogs.tsfonksiyonunu yazın.- Page'i async yapın; await ile veriyi çekin.
- Liste için ayrı Client Component yalnızca arama/filtre gerekiyorsa ekleyin.
// app/[locale]/(main)/blog/page.tsx
export default async function BlogPage() {
const blogs = await getPublishedBlogs({ limit: 20 });
return <BlogList blogs={blogs} />;
}
Bölüm 3: Streaming ve UX
Yavaş sorgu tüm sayfayı bloke etmemeli. loading.tsx route segmentine Suspense boundary ekler.
Adım adım uygulama
Aşağıdaki sırayı takip edin. Her adımı tamamlamadan bir sonrakine geçmeyin; özellikle güvenlik ve veri katmanı adımları atlanmamalıdır.
- Blog listesi için skeleton component tasarlayın.
- Ağır alt segmenti
<Suspense fallback={...}>ile sarın. - Core Web Vitals'ta LCP ve INP'yi ölçün.
İpucu: Layout'ta ağır async iş yapmayın; alt route'lara bölün.
Bölüm 4: Cache ve revalidate
Next.js 16'da fetch cache davranışı bilinçli olarak explicit'tir. Dinamik sayfalar için cache: "no-store" veya dynamic = "force-dynamic" kullanın.
Blog içeriği güncellendiğinde revalidatePath("/blog") veya tag ile hedefli invalidation yapın.
Dikkat: Development ve production cache farklıdır; yalnızca local hızına güvenerek strateji seçmeyin.
Bölüm 5: Partial Prerendering ve dinamik bölgeler
Next.js 15+ ile statik kabuk + dinamik delikler (PPR) birleşebilir. Blog listesi gibi sayfalarda hero statik, filtre/search dinamik tutulabilir.
export const experimental_ppr = true ve Suspense sınırları ile TTFB iyileşir. Dinamik segmentlerin cache politikası ayrı düşünülmeli.
Adım adım uygulama
Aşağıdaki sırayı takip edin. Her adımı tamamlamadan bir sonrakine geçmeyin; özellikle güvenlik ve veri katmanı adımları atlanmamalıdır.
- Sayfayı statik/dinamik parçalara ayırın.
- Dinamik parça için
loading.tsxskeleton ekleyin. - Lighthouse ile LCP ve INP ölçün.
Bölüm 6: Deploy ve ortam değişkenleri
Server Component'ler build zamanında bazı env'leri gömer; runtime secret için dikkat.
Production ortamında Next.js App Router ile ilgili en sık görülen sorun, geliştirme ortamındaki varsayımların (küçük veri seti, tek kullanıcı, sıcak cache) canlı trafikte çökmemesidir. Bu yüzden her değişiklikten önce yük testi veya en azından p95 latency ölçümü yapın.
Structured logging (request id, route, süre, kullanıcı id’si — PII olmadan) ve hata oranı alarmları, sorunları kullanıcı şikayetinden önce yakalamanızı sağlar. Log’da stack trace tutun; kullanıcıya generic mesaj gösterin.
Dokümantasyonu kod ile birlikte güncelleyin: README, ADR (Architecture Decision Record) veya ekip wiki’sinde “neden bu kararı aldık?” sorusunun cevabı gelecekteki sizin en büyük yardımcınızdır.
Dikkat: NEXT_PUBLIC_ öneki olmayan secret'ları asla client bundle'a sızdırmayın.
Sık yapılan hatalar
Aşağıdaki tuzaklar eğitim ortamlarında nadiren, production'da ise pahalıya mal olur. Code review checklist'inize eklemenizi öneririz.
- Tüm ağacı "use client" ile işaretlemek
- useEffect ile sunucuda yapılabilecek veriyi çekmek
- Server'dan Client'a fonksiyon veya class instance geçirmek
Pratik alıştırmalar
Okumak yeterli değildir; öğrenmeyi pekiştirmek için küçük bir side-project veya mevcut kod tabanınızda şu görevleri uygulayın:
- Bir sayfayı Server-only yapıp bundle analyzer ile farkı ölçün
- Blog detayına Suspense ile yorum listesi ekleyin
- Publish sonrası revalidatePath çağrısı ekleyin
Özet ve sonraki adımlar
Bu rehberdeki prensipleri tek seferde tüm projeye uygulamaya çalışmayın. Önce tek bir route veya modül seçin, ölçün, sonra yaygınlaştırın.
- Server Actions öğreticisi ile mutasyon katmanını öğrenin
- next-intl ile locale routing'i derinleştirin
- Partial Prerendering dokümantasyonunu takip edin