Erro Hydration failed no Next.js: causas reais e solução
Se você está vendo o erro “Erro Hydration failed no Next.js because the initial UI does not match what was rendered on the server” em um projeto Next.js, a boa notícia é: isso é um problema comum e, na maioria dos casos, tem solução simples.
Esse erro acontece quando o HTML gerado no servidor é diferente do HTML gerado no cliente, e o React não consegue “ligar” (hidratar) corretamente os dois.
Neste artigo, você vai entender o que esse erro significa, por que ele acontece e como resolver de forma segura, sem gambiarras.
Resumo rápido (pra quem está com pressa)
👉 O erro Hydration failed acontece quando o conteúdo renderizado no servidor não bate com o que o navegador tenta renderizar depois.
👉 Geralmente é causado por código que depende do navegador, valores dinâmicos ou estado inicial inconsistente.
👉 A solução quase sempre envolve adiar esse código para o client-side ou ajustar a forma como os dados são renderizados.
Agora vamos com calma.
O que significa o erro “Hydration failed” no Next.js?
O Next.js usa Server-Side Rendering (SSR). Isso significa que:
- O servidor gera o HTML inicial
- Esse HTML é enviado para o navegador
- O React “hidrata” esse HTML, tornando-o interativo
O erro aparece quando o React percebe que:
“O HTML que eu renderizei no servidor não é igual ao que estou tentando renderizar no cliente.”
Quando isso acontece, o React não confia no resultado e dispara o erro de hidratação.
Exemplo simples de código que causa o erro
Veja este exemplo:
export default function Page() {
return <p>{Date.now()}</p>;
}
Por que isso quebra?
- No servidor,
Date.now()gera um valor - No cliente,
Date.now()gera outro valor - O HTML não bate
- 💥 Erro de hidratação
O mesmo vale para:
Math.random()windowlocalStoragedocument
Causas mais comuns do erro “Hydration failed”
👉 Veja também “Hooks como o useEffect precisam ser usados com cuidado para evitar renderizações inesperadas.”
Código que roda apenas no navegador
Exemplo clássico:
export default function Page() {
return <p>{window.innerWidth}</p>;
}
No servidor, window não existe.
No cliente, existe.
Resultado: HTML diferente → erro.
Valores dinâmicos renderizados no servidor
Qualquer valor que muda a cada render pode causar problemas:
- datas
- números aleatórios
- dados baseados em horário
- estados derivados de APIs externas
Se o valor não for previsível, ele não deve ser renderizado no servidor.
Estado inicial inconsistente
👉 Veja também “Esse problema aparece muito em funcionalidades como dark mode.”
Outro erro comum:
const [theme, setTheme] = useState(
localStorage.getItem("theme")
);
No servidor:
localStoragenão existe
No cliente:
- existe e retorna valor
Mais uma vez: HTML diferente.
Como resolver o erro “Hydration failed” no Next.js
Agora a parte importante.
1️⃣ Use useEffect para código client-side
Se algo depende do navegador, execute após a montagem do componente.
import { useEffect, useState } from "react";
export default function Page() {
const [width, setWidth] = useState(null);
useEffect(() => {
setWidth(window.innerWidth);
}, []);
return <p>{width}</p>;
}
Assim:
- servidor renderiza algo previsível
- cliente ajusta depois
- hidratação funciona
2️⃣ Verifique se está no navegador
Outra abordagem comum:
if (typeof window === "undefined") {
return null;
}
Isso evita que o código execute no servidor.
⚠️ Use com cuidado para não esconder conteúdo importante.
3️⃣ Desabilite SSR para componentes específicos
Quando faz sentido, você pode carregar um componente apenas no cliente:
import dynamic from "next/dynamic";
const ClientOnlyComponent = dynamic(
() => import("./ClientOnlyComponent"),
{ ssr: false }
);
Essa é uma solução limpa para:
- gráficos
- bibliotecas que dependem do DOM
- widgets externos
4️⃣ Ajuste o estado inicial corretamente
Evite depender de valores dinâmicos no useState inicial.
Em vez disso:
const [theme, setTheme] = useState(null);
useEffect(() => {
setTheme(localStorage.getItem("theme"));
}, []);
Isso mantém o HTML inicial consistente.
Quando você NÃO precisa se preocupar tanto
👉 Veja também “Quando o problema acontece apenas em produção, o backend também pode estar envolvido.”
Nem todo erro de hidratação é o fim do mundo.
Você pode ficar mais tranquilo quando:
- o erro aparece apenas em desenvolvimento
- o layout não quebra
- o comportamento em produção está correto
Mesmo assim, vale corrigir para evitar problemas futuros.
Boas práticas para evitar esse erro no futuro
- Não renderize valores imprevisíveis no servidor
- Separe claramente código server e client
- Use
useEffectpara efeitos colaterais - Evite lógica complexa no render inicial
- Teste o build de produção antes do deploy
Essas práticas evitam 90% dos erros de hidratação.
Uma dica prática para quem está em produção
Esse erro costuma aparecer:
- perto do deploy
- em builds que “sempre funcionaram”
- depois de pequenas mudanças
Antes de entrar em pânico:
- veja qual componente causou o erro
- procure por valores dinâmicos
- verifique uso de
window,documentelocalStorage
Na maioria das vezes, a correção é simples.
Conclusão
O erro “Hydration failed” no Next.js é assustador à primeira vista, mas quase nunca é um problema grave.
Ele acontece porque:
- servidor e cliente renderizam coisas diferentes
- o React percebe isso e avisa
Com pequenos ajustes — geralmente movendo lógica para o client-side — o problema desaparece.
Agora você já sabe onde olhar, o que corrigir e quando se preocupar.



