| name | nextjs_specialist |
| description | Next.js 15 App Router, Server Components, SSR/SSG optimizasyonu ve modern Next.js best practices. |
⚛️ Next.js Specialist
Next.js 15 App Router ve Server Components rehberi.
📋 İçindekiler
- App Router Temelleri
- Server vs Client Components
- Data Fetching
- Rendering Stratejileri
- Optimizasyon
1. App Router Temelleri
Dosya Yapısı
app/
├── layout.tsx # Root layout
├── page.tsx # Home page (/)
├── loading.tsx # Loading UI
├── error.tsx # Error boundary
├── not-found.tsx # 404 page
├── globals.css
│
├── (marketing)/ # Route group (URL'de görünmez)
│ ├── about/
│ │ └── page.tsx # /about
│ └── contact/
│ └── page.tsx # /contact
│
├── dashboard/
│ ├── layout.tsx # Nested layout
│ ├── page.tsx # /dashboard
│ └── settings/
│ └── page.tsx # /dashboard/settings
│
├── blog/
│ ├── page.tsx # /blog
│ └── [slug]/
│ └── page.tsx # /blog/:slug (dynamic)
│
└── api/
└── users/
└── route.ts # API route
Special Files
| Dosya | Amaç |
|---|
layout.tsx | Shared layout, state korunur |
page.tsx | Unique route content |
loading.tsx | Suspense fallback |
error.tsx | Error boundary |
not-found.tsx | 404 handler |
route.ts | API endpoint |
2. Server vs Client Components
Server Components (Default)
async function UsersPage() {
const users = await db.users.findMany();
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UsersPage;
Client Components
'use client';
import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);
}
Composition Pattern
import { Counter } from './Counter';
async function Dashboard() {
const data = await fetchData();
return (
<div>
<h1>{data.title}</h1>
<Counter /> {/* Client Component */}
</div>
);
}
Ne Zaman Hangisi?
| Server Component | Client Component |
|---|
| Data fetching | Interactivity (onClick, onChange) |
| Backend erişimi | Browser API (localStorage) |
| Sensitive logic | Hooks (useState, useEffect) |
| Büyük dependencies | Event listeners |
3. Data Fetching
Server Components
async function Page() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return <div>{data.title}</div>;
}
const res = await fetch(url, {
cache: 'force-cache',
});
Server Actions
'use server';
export async function createUser(formData: FormData) {
const name = formData.get('name');
await db.users.create({ data: { name } });
revalidatePath('/users');
}
import { createUser } from './actions';
export default function Page() {
return (
<form action={createUser}>
<input name="name" />
<button type="submit">Create</button>
</form>
);
}
4. Rendering Stratejileri
Static (SSG)
export default function Page() {
return <h1>Static Page</h1>;
}
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map(post => ({ slug: post.slug }));
}
Dynamic (SSR)
export const dynamic = 'force-dynamic';
export default async function Page() {
const data = await fetchRealTimeData();
return <div>{data.value}</div>;
}
Incremental Static Regeneration (ISR)
export const revalidate = 60;
export default async function Page() {
const data = await fetchData();
return <div>{data.value}</div>;
}
5. Optimizasyon
Image Optimization
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // LCP için
placeholder="blur"
blurDataURL="data:image/..."
/>
Font Optimization
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
});
export default function Layout({ children }) {
return (
<html className={inter.className}>
<body>{children}</body>
</html>
);
}
Metadata
export const metadata = {
title: 'My App',
description: 'App description',
};
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
title: post.title,
openGraph: { images: [post.image] },
};
}
Parallel Routes
app/
├── @modal/
│ └── login/page.tsx
├── @sidebar/
│ └── page.tsx
└── layout.tsx
export default function Layout({ children, modal, sidebar }) {
return (
<>
{sidebar}
{children}
{modal}
</>
);
}
Next.js Specialist v1.1 - Enhanced
🔄 Workflow
Kaynak: Next.js App Router Documentation & Vercel Security Guide
Aşama 1: Rendering Strategy
Aşama 2: Data & Actions
Aşama 3: Performance (Core Web Vitals)
Kontrol Noktaları
| Aşama | Doğrulama |
|---|
| 1 | "Hydration Error" alıyor musun? (Server/Client HTML uyuşmazlığı) |
| 2 | LCP (Largest Contentful Paint) < 2.5s mi? |
| 3 | Hassas veriler (API Key) Client bundle'a sızıyor mu? |