Cómo solucionar el error Hydration Mismatch en aplicaciones de Next.js
El Diagnóstico Rápido
El error de hidratación en Next.js (Error: Hydration failed because the initial UI does not match what was rendered on the server) ocurre cuando el HTML renderizado por el servidor contiene valores dinámicos (tales como fechas con zonas horarias locales, números aleatorios o estados del objeto window) que cambian instantáneamente al cargarse en el navegador del cliente.
🚀 Cómo solucionar el error paso a paso
Paso 1: Identificar el nodo del DOM en conflicto en la consola de depuración
Abre la consola de desarrollador de tu navegador (F12) al ocurrir el fallo. Next.js mostrará un reporte de inconsistencia detallando qué elemento HTML difiere entre el servidor y el cliente:
# Alerta en la consola de depuración
Warning: Text content did not match. Server: "08:30" Client: "14:30"
Paso 2: Utilizar un hook de estado para renderizar solo tras la hidratación
Asegura que el componente que depende del estado local del cliente (como la zona horaria del sistema o el objeto localStorage) solo se renderice una vez que el componente se haya montado por completo en el navegador:
import { useState, useEffect } from 'react';
export default function MiComponenteDinamico() {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
// Confirmar que el cliente está listo
setIsClient(true);
}, []);
return (
<div>
{isClient ? new Date().toLocaleTimeString() : 'Cargando...'}
</div>
);
}
Paso 3: Desactivar SSR de forma selectiva para componentes dinámicos
Si necesitas omitir por completo el renderizado del lado del servidor para un componente que dependa de metadatos locales del cliente, utiliza la importación dinámica de Next.js:
import dynamic from 'next/dynamic';
// Importar el componente dinámico desactivando el Server-Side Rendering
const ComponenteSinSSR = dynamic(() => import('../components/MiReloj'), {
ssr: false
});
Consejo de Prevención
Prácticas de seguridad recomendadas:
- No utilices la directiva
suppressHydrationWarningen etiquetas HTML padres contenedoras si no es estrictamente necesario para un elemento final de texto plano (como una fecha corta). Activar esta bandera no soluciona el fallo subyacente; únicamente silencia la advertencia visual en consola, lo que provoca que React no logre asociar correctamente los eventos e interacciones Javascript al árbol del DOM real de Next.js, degradando el rendimiento general de la página.