Ulaşım
- Adres:Batıkent Mh. 8910 Sk. 6. Etap 1H No: 18 Yeni Toki Eyyübiye / Şanlıurfa (Yeni Alım Satım Karşısı)
- Telefon:0 (545) 528 88 93
- eMail: info@alestaweb.com
Next.js 15 ile çalışırken "Hydration failed because the initial UI does not match" hatası mı alıyorsunuz? Panik yapmayın! Alesta Web olarak bu rehberde hydration mismatch error'ün ne olduğunu ve nasıl çözüleceğini (how to fix) detaylıca anlatacağız. React 19 ile gelen değişiklikler bu hatayı daha da yaygın hale getirdi.
Hydration, server-side rendering (SSR) yapan framework'lerde kritik bir kavramdır. Şöyle düşünün: Sunucu tarafında HTML oluşturulur ve tarayıcıya gönderilir. Sonra React, bu HTML'i "canlandırır" (hydrate eder) ve interaktif hale getirir. İşte bu sürece hydration denir.
Alesta Web olarak Next.js projelerinde bu hatayı sıkça görüyoruz. Hata mesajı genellikle şöyle görünür:
Error: Hydration failed because the initial UI does not match
what was rendered on the server.
Warning: Text content does not match server-rendered HTML.
Server: "Hello World" Client: "Hello undefined"
See more info here: https://nextjs.org/docs/messages/react-hydration-error
Hydration error, sunucuda oluşturulan HTML ile client'ta oluşturulan HTML'in eşleşmediğini gösterir. Bu ciddi bir sorun olabilir çünkü UI tutarsızlıklarına yol açar!
Hydration mismatch hatasının birçok nedeni olabilir. Alesta Web deneyimlerimize göre en yaygın nedenler şunlardır:
// Bu kod hydration error verir!
function MyComponent() {
const width = window.innerWidth; // ❌ Server'da window yok!
return <div>Width: {width}</div>;
}
// Sunucu ve client farklı zaman gösterir
function Clock() {
return <div>{new Date().toLocaleTimeString()}</div>; // ❌ Mismatch!
}
// Math.random() her seferinde farklı sonuç verir
function RandomGreeting() {
const greetings = ['Merhaba', 'Selam', 'Hey'];
const index = Math.floor(Math.random() * greetings.length);
return <h1>{greetings[index]}</h1>; // ❌ Server vs Client farklı!
}
Next.js 15 ve React 19 kombinasyonunda bazı browser extension'lar HTML'e ekstra attribute ekler. Örneğin ColorZilla extension'ı cz-shortcut-listen="true" attribute'u ekler ve hydration error'a neden olur.
function UserPreferences() {
// localStorage server'da mevcut değil!
const theme = localStorage.getItem('theme'); // ❌ Error!
return <div className={theme}>Content</div>;
}
Alesta Web olarak yüzlerce projede bu hataları çözdük. İşte kanıtlanmış çözümler:
import { useState, useEffect } from 'react';
function WindowWidth() {
const [width, setWidth] = useState(0);
useEffect(() => {
// Bu kod sadece client'ta çalışır
setWidth(window.innerWidth);
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
// İlk render'da 0 göster (server ile eşleşir)
if (width === 0) return null;
return <div>Window width: {width}px</div>;
}
import dynamic from 'next/dynamic';
// Bu component sadece client'ta render edilir
const ClientOnlyMap = dynamic(() => import('./Map'), {
ssr: false,
loading: () => <p>Harita yükleniyor...</p>
});
function MapPage() {
return (
<div>
<h1>Konum Haritası</h1>
<ClientOnlyMap />
</div>
);
}
// Sadece TEK SEVİYE derinliğinde çalışır
function DateDisplay() {
return (
<time suppressHydrationWarning>
{new Date().toLocaleDateString()}
</time>
);
}
// UYARI: Bu bir escape hatch'tir, sorunu çözmez sadece gizler!
suppressHydrationWarning sadece kaçınılmaz durumlarda kullanılmalıdır. Sorunu çözmez, sadece uyarıyı gizler. Alesta Web olarak öncelikle asıl sorunu çözmenizi öneriyoruz.
Dark mode için next-themes kullanıyorsanız, hydration hatası çok yaygındır:
// app/providers.tsx
'use client';
import { ThemeProvider } from 'next-themes';
export function Providers({ children }) {
return (
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
);
}
// Component'te kullanım
'use client';
import { useTheme } from 'next-themes';
import { useEffect, useState } from 'react';
function ThemeToggle() {
const [mounted, setMounted] = useState(false);
const { theme, setTheme } = useTheme();
useEffect(() => {
setMounted(true);
}, []);
// Mounting öncesi render etme (hydration mismatch önlenir)
if (!mounted) return null;
return (
<button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
{theme === 'dark' ? '?' : '☀️'}
</button>
);
}
import Script from 'next/script';
function AnalyticsPage() {
return (
<>
{/* afterInteractive: hydration sonrası yükle */}
<Script
src="https://www.googletagmanager.com/gtag/js?id=GA_ID"
strategy="afterInteractive"
/>
{/* lazyOnload: sayfa tamamen yüklendikten sonra */}
<Script
src="https://widget.example.com/embed.js"
strategy="lazyOnload"
/>
</>
);
}
'use client';
import { useState, useEffect } from 'react';
function useLocalStorage<T>(key: string, initialValue: T) {
// Server'da initialValue kullan
const [storedValue, setStoredValue] = useState<T>(initialValue);
useEffect(() => {
// Client'ta localStorage'dan oku
try {
const item = window.localStorage.getItem(key);
if (item) {
setStoredValue(JSON.parse(item));
}
} catch (error) {
console.warn(`Error reading localStorage key "${key}":`, error);
}
}, [key]);
const setValue = (value: T) => {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue] as const;
}
// Kullanım
function Settings() {
const [fontSize, setFontSize] = useLocalStorage('fontSize', 16);
return (
<div style={{ fontSize }}>
<button onClick={() => setFontSize(fontSize + 2)}>Büyüt</button>
<button onClick={() => setFontSize(fontSize - 2)}>Küçült</button>
</div>
);
}
'use client';
import { useState, useEffect } from 'react';
function ClientOnlyComponent({ children }) {
const [hasMounted, setHasMounted] = useState(false);
useEffect(() => {
setHasMounted(true);
}, []);
if (!hasMounted) {
// Server ile aynı içeriği döndür (veya null)
return null;
}
return <>{children}</>;
}
// Kullanım
function App() {
return (
<ClientOnlyComponent>
<BrowserOnlyFeature />
</ClientOnlyComponent>
);
}
Alesta Web olarak Next.js projelerinde şu kurallara uyuyoruz:
# React DevTools ile inspect et
# Console'da hydration uyarılarını ara
# SSR çıktısını kontrol et
curl -s http://localhost:3000 | grep -i "hydration"
# Build ve analiz
npm run build
# "Hydration" kelimesini içeren uyarıları kontrol et
Alesta Web olarak tüm çözümleri test ettik ve doğruladık.
Artık Next.js 15 hydration mismatch error (hydration hatası) sizin için bir sorun olmaktan çıktı! Alesta Web olarak anlattığımız yöntemlerle bu hatayı kolayca çözebilirsiniz.
Hızlı Özet / Quick Summary:
Faydalı Linkler / Useful Links:
© 2026 AlestaWeb - Tüm hakları saklıdır.