Next.js 15 & React 19 .cursorrules: Server Action ve Hydration Çöplüğünü Yok Etme Rehberi
Next.js 15'te Yapay Zeka Neden Sürekli Eski Kod Üretiyor?
Cursor, Windsurf veya Copilot gibi yapay zeka araçlarına *"Next.js projemde kullanıcı profilini getiren bir sayfa yaz"* dediğinizde, modellerin ezici çoğunluğu 2021–2023 yıllarındaki GitHub kodlarıyla eğitildiği için hemen şu ölümcül anti-pattern'lere sarılır:
1. **Gereksiz `'use client'` Şişkinliği:** İstemci tarafında hiçbir tarayıcı olayı veya form etkileşimi olmamasına rağmen dosyanın tepesine `'use client'` çakar. Bu durum Next.js 15'in streaming ve Server Component avantajlarını çöpe atar, bundle boyutunu anlamsızca büyütür. 2. **Hortlak `useEffect` ile Veri Çekme:** Veriyi sunucuda doğrudan asenkron bileşen içinde çekmek yerine, istemcide `useEffect` içine `fetch()` yerleştirip yapay `loading` state'leri oluşturur. Bu da kullanıcıya beyaz ekran titremeleri (layout shift) ve yarış koşulları (race condition) yaşatır. 3. **Güvensiz ve Doğrulanmamış Server Actions:** Server Action parametrelerini doğrudan SQL sorgusuna yollar; Zod veya Valibot ile runtime tip doğrulaması yapmayı unutur.
// ❌ KONTROLSÜZ YAPAY ZEKANIN ÜRETTİĞİ ÇÖP KOD:
'use client';
import { useEffect, useState } from 'react';export default function UserProfile({ id }: any) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true);
useEffect(() => { fetch('/api/user?id=' + id) .then((res) => res.json()) .then((d) => { setData(d); setLoading(false); }); }, []);
if (loading) return <div>Yükleniyor...</div>; return <div>{data?.name}</div>; } ```
---
Sıfır-Slop Mimari Çözümü: .cursorrules Kalkanı
Projenizin kök dizinine cerrahi bir `.cursorrules` veya `.cursor/rules/nextjs.mdc` kuralı yerleştirdiğinizde, yapay zekanın istemci/sunucu sınırını zorunlu olarak tanımasını sağlarsınız. Model artık React 19 standartlarını tavizsiz uygular:
// ✔ FCKAISLOP KURALLARIYLA ZORLANAN SENYOR MİMARİ:
import { z } from 'zod';
import { db } from '@/lib/db';
import { auth } from '@/lib/auth';
import { notFound } from 'next/navigation';const UserQuerySchema = z.object({ id: z.string().uuid('Geçersiz kullanıcı kimliği'), });
interface UserProfileProps { id: string; }
// 1. Varsayılan olarak asenkron Server Component — sıfır 'use client', sıfır useEffect! export async function UserProfile({ id }: UserProfileProps) { // 2. Sunucu sınırında oturum kontrolü const session = await auth(); if (!session?.userId) return notFound();
// 3. Çalışma zamanı Zod doğrulaması const parsed = UserQuerySchema.safeParse({ id }); if (!parsed.success) { return <div className="text-red-500 font-mono">Geçersiz ID formatı</div>; }
// 4. Doğrudan sunucu katmanından sorgu — sıfır ekstra network gecikmesi const user = await db.user.findUnique({ where: { id: parsed.data.id }, select: { id: true, name: true, email: true }, });
if (!user) return notFound();
return ( <div className="p-4 rounded-xl bg-zinc-900 border border-zinc-800"> <h2 className="text-lg font-bold text-zinc-100">{user.name}</h2> <p className="text-xs text-zinc-400 font-mono">{user.email}</p> </div> ); } ```
---
Senyor Geliştirici İçin Altın Kurallar: - **Her zaman Server First:** State, browser window objesi veya `onClick` gerekmedikçe ASLA `'use client'` ekletmeyin. - **Zod Güvenlik Sınırı:** Veritabanına veya harici servise dokunan her Server Action istisnasız `safeParse` ile doğrulanmalı. - **Yapılandırılmış Hata Tipleri:** Hata durumlarında sunucudan ham stack trace fırlatmak yerine `{ success: false, error: '...' }` şeklinde ayrıştırılmış tipler dönün.
Tüm Kural Paketini İndirin
Cursor, Claude Code ve Windsurf için 8 amiral gemisi kural paketinin tamamı (Tek seferlik ₺590).