Ömer Özbay
Next.js App Router
Next.js React

Next.js 14 App Router: Pages Router'dan Geçiş Rehberi

18 Kasım 2024 16 dk okuma 5.1K görüntülenme

Next.js 14 ile App Router artık production-ready. Peki mevcut Pages Router projenizi nasıl geçireceksiniz? Bu yazıda gerçek bir projeyi adım adım migrate ettim ve öğrendiklerimi paylaşıyorum.

App Router vs Pages Router: Temel Farklar

App Router, React'ın Server Components modelini tam anlamıyla benimsiyor. Bu, Pages Router'dan köklü bir paradigma değişikliği demek.

  • Varsayılan olarak Server Component: 'use client' eklemediğiniz her bileşen sunucuda çalışır
  • Nested layouts: Her route segmenti kendi layout'una sahip olabilir, layout state'i korunur
  • Parallel ve Intercepting Routes: Modal pattern'ları artık URL-based
  • Server Actions: Form submit için ayrı API route yazmaya gerek yok

Dosya Yapısı Değişiklikleri

# Pages Router pages/ index.tsx → app/page.tsx about.tsx → app/about/page.tsx blog/[slug].tsx → app/blog/[slug]/page.tsx _app.tsx → app/layout.tsx _document.tsx → app/layout.tsx (head yönetimi) api/posts.ts → app/api/posts/route.ts

getServerSideProps → async Server Component

Pages Router'daki getServerSideProps artık gerekmiyor. Bileşeni doğrudan async yapıp veri çekebilirsiniz.

// ÖNCE — Pages Router export async function getServerSideProps() { const posts = await fetchPosts(); return { props: { posts } }; } export default function Blog({ posts }) { ... } // SONRA — App Router export default async function Blog() { const posts = await fetchPosts(); // doğrudan await return <PostList posts={posts} />; }

Server Actions ile Form Yönetimi

'use server'; async function createPost(formData: FormData) { const title = formData.get('title') as string; await db.insert(posts).values({ title }); revalidatePath('/blog'); } // Client component'ta <form action={createPost}> <input name="title" /> <button type="submit">Yayınla</button> </form>

Metadata API

Her page.tsx veya layout.tsx dosyasından metadata export ederek SEO yönetimi artık çok daha temiz.

// app/blog/[slug]/page.tsx export async function generateMetadata({ params }) { const post = await getPost(params.slug); return { title: post.title, description: post.excerpt, openGraph: { images: [post.coverImage] }, }; }

Geçiş Stratejisi

  • App Router ve Pages Router aynı projede birlikte çalışabilir — kademeli geçiş mümkün
  • Önce _app.tsx ve _document.tsx'i app/layout.tsx'e taşıyın
  • Statik sayfalardan başlayın, dinamik sayfaları sonraya bırakın
  • next/navigation hook'larını next/router yerine kullanmayı unutmayın

Performans Sonuçları

Gerçek projemizde App Router'a geçiş sonrası ölçümler:

  • JavaScript bundle: 340KB → 180KB (%47 azalma)
  • LCP: 2.8s → 0.9s
  • TTFB: 420ms → 95ms
  • Lighthouse Performance skoru: 71 → 96

Sonuç

App Router'a geçiş başlangıçta zorlayıcı görünse de, Server Components ve Server Actions'ın getirdiği sadelik ve performans kazanımları buna değiyor. Yeni projeler için doğrudan App Router ile başlamanızı öneririm.

Faydalı buldunuz mu? Bu içeriği kendi ağınızla paylaşarak bana destek olabilirsiniz.