¿Qué es el Error de 'Hydration Failed' en React y Next.js?
El error Hydration Failed o Text content does not match server-rendered HTML ocurre comúnmente en frameworks que utilizan Server-Side Rendering (SSR) como Next.js o Remix. Sucede cuando el HTML generado por el servidor no coincide exactamente con el primer renderizado que realiza el cliente (navegador) al cargar la aplicación. Esto genera una discrepancia en el DOM virtual que rompe la interfaz de usuario y afecta la experiencia de usuario y el SEO técnico.
Principales Causas del Error de Hidratación
Identificar la causa raíz es fundamental para aplicar la solución correcta. Entre los motivos más frecuentes se encuentran:
- Uso de funciones que devuelven valores dinámicos diferentes en cada ejecución, como
new Date(),Math.random()olocalStoragedirectamente en el renderizado inicial. - Extensiones del navegador que inyectan atributos o etiquetas HTML adicionales en el elemento
<body>antes de que React tome el control. - Etiquetas HTML mal anidadas, por ejemplo, colocar un bloque
<p>dentro de otro<p>o un<div>dentro de un<span>, lo que el navegador corrige automáticamente alterando el DOM, pero React no lo espera.
Método 1: Usar useEffect para Código Dependiente del Cliente
La forma más limpia de evitar que el servidor y el cliente difieran en el primer render es asegurar que el código dependiente del navegador solo se ejecute después de que el componente se haya montado.
- Identifica la variable o función que causa el conflicto, por ejemplo,
window.innerWidthonew Date().toLocaleTimeString(). - Crea un estado local inicializado con un valor estático por defecto (ej.
nullofalse). - Utiliza el hook
useEffectpara actualizar ese estado una vez que el componente esté en el cliente.
Ejemplo de código corregido:
const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); }, []); return <div>{isClient ? window.innerWidth : 'Cargando...'}</div>;Método 2: Deshabilitar el SSR en Componentes Específicos
Si estás utilizando un componente de terceros que manipula directamente el DOM o accede a objetos globales del navegador sin soporte SSR, puedes desactivar el renderizado en servidor para ese componente en específico.
- Si usas Next.js, importa tu componente utilizando
next/dynamic. - Configura la opción
ssr: falseen la importación dinámica.
Ejemplo de implementación:
import dynamic from 'from 'next/dynamic'; const DynamicComponentWithNoSSR = dynamic(() => import('../components/HeavyWidget'), { ssr: false }); export default function Page() { return <Div><DynamicComponentWithNoSSR /></Div>; }Método 3: Utilizar el Atributo suppressHydrationWarning
En ocasiones, las diferencias de contenido son inevitables y totalmente inofensivas, como las marcas de tiempo generadas en el servidor frente al cliente con diferencias de milisegundos.
- Localiza la etiqueta JSX exacta que genera la advertencia en la consola de desarrollo.
- Añade la propiedad
suppressHydrationWarning={true}directamente en el elemento afectado.
Ejemplo de uso:
<time suppressHydrationWarning={true}>{new Date().toISOString()}</time>Aplicando estos métodos podrás eliminar por completo los errores de hidratación y garantizar una transición fluida entre el servidor y el cliente en tus aplicaciones web modernas.