Erro de Hidratação no Next.js: Causas e Soluções
Descubra as causas reais do erro de hidratação no Next.js e aprenda a corrigir divergências de HTML, datas e fusos horários de forma definitiva.

O que é o erro de hidratação no Next.js e por que ele acontece
O erro de hidratação no Next.js ocorre quando existe uma divergência entre a árvore React pré-renderizada no servidor e a árvore de componentes gerada na primeira renderização dentro do navegador. A hidratação é o processo em que o React converte o HTML pré-renderizado vindo do servidor em uma aplicação interativa, anexando os manipuladores de eventos (event handlers) aos elementos do DOM.
Quando o React detecta que o HTML enviado pelo servidor não corresponde exatamente ao que o cliente renderizou na inicialização, ele dispara o aviso de erro de hidratação. Resolver esse problema exige identificar onde a estrutura do servidor e a do cliente se dividiram, garantindo que o código responda de forma idêntica em ambos os ambientes antes da interatividade.
Ao estruturar seu projeto, garantir que o código rode de forma consistente no servidor e no navegador previne falhas de renderização. Se você está desenvolvendo ou planejando quanto tempo leva para fazer um site, dominar o fluxo de hidratação é indispensável para a qualidade do código em produção.
Principais pontos
- Conceito essencial: hidratação é o momento em que o React anexa os event handlers ao HTML vindo do servidor.
- Causa raiz: diferenças de marcação HTML, dados de data/fuso ou APIs do navegador entre o servidor e o cliente.
- Comportamento do iOS: dispositivos da Apple convertem números e e-mails em links automaticamente se não forem configurados.
- Soluções oficiais: uso de
useEffect, importação dinâmica comnext/dynamice a propsuppressHydrationWarning.
Principais causas de erros de hidratação em projetos Next.js
A documentação oficial do Next.js sobre erros de hidratação detalha os cenários que geram inconsistência entre a pré-renderização no servidor e o navegador.
Aninhamento incorreto de tags HTML
O navegador tenta corrigir automaticamente HTML inválido antes do React hidratar a página. Quando a marcação enviada pelo servidor possui elementos aninhados incorretamente, a árvore do DOM é reestruturada pelo navegador, resultando em uma divergência com a árvore do React. Os casos mais comuns incluem:
- Um parágrafo (
<p>) dentro de outro parágrafo (<p>). - Uma
<div>inserida dentro de um parágrafo (<p>). - Uma lista (
<ul>ou<ol>) dentro de um parágrafo (<p>). - Conteúdo interativo aninhado, como um link (
<a>) dentro de outro link (<a>) ou um botão (<button>) dentro de outro botão (<button>).
Uso de APIs exclusivas do navegador e checagens typeof window
Chamar APIs que existem apenas no ambiente do cliente (como window ou localStorage) durante a fase de renderização faz com que o servidor não consiga executar o mesmo trecho de código. Da mesma forma, adicionar condicionais do tipo typeof window !== 'undefined' diretamente na lógica de renderização altera a estrutura gerada: o servidor renderiza uma ramificação e o navegador renderiza outra no primeiro render.
Construtor Date(), datas e fusos horários
APIs dependentes do tempo, como o construtor Date(), são fontes frequentes de erros. Se o servidor do Next.js processar a requisição configurado com o fuso horário UTC e o navegador do usuário estiver no fuso horário de São Paulo, o texto impresso na tela será diferente nos dois lados. Essa diferença no HTML gerado quebra a hidratação. Como abordado nas discussões do repositório next-intl no GitHub, gerenciar dados de localização e fuso exige atenção redobrada.
Comportamento automático do iOS Safari
Em dispositivos iOS, o sistema operacional injeta links automaticamente sobre sequências numéricas (que interpreta como telefones) e endereços de e-mail encontrados no texto. Essa modificação no HTML diretamente pelo sistema cria nós extras que não existiam no servidor, disparando o erro de hidratação.
Extensões, CSS-in-JS e serviços de CDN/Edge
Outros fatores externos também alteram a resposta recebida pelo navegador:
- Extensões de navegador: add-ons que modificam a árvore do DOM inserindo scripts ou elementos.
- Bibliotecas CSS-in-JS mal configuradas: quando a extração do CSS crítico não é sincronizada entre servidor e cliente.
- CDN e redes Edge: serviços que alteram a resposta do servidor. Um exemplo nominalmente citado na documentação do Next.js é o recurso Auto Minify da Cloudflare, que modifica o HTML antes de entregá-lo ao cliente.
"A hidratação quebra sempre que o HTML enviado pelo servidor não coincide perfeitamente com o primeiro resultado da renderização no cliente."
Tabela comparativa: causa do erro vs. correção recomendada
| Causa da divergência | Origem do problema | Correção recomendada |
|---|---|---|
| Aninhamento inválido | HTML semanticamente incorreto (ex: div em p) |
Corrigir as tags HTML para respeitar a especificação do DOM |
APIs de navegador (localStorage, window) |
Acesso a dados que não existem no servidor | Executar a leitura dentro do useEffect com estado isClient |
| Datas e fuso horário divergentes | Servidor em UTC e cliente no fuso local | Usar Intl.DateTimeFormat com timeZone fixo ou formatar no servidor |
| Auto-formatação do iOS | Sistema converte texto em links de telefone/e-mail | Adicionar meta tag format-detection no layout |
| Componentes exclusivos de cliente | Dependência pesada do navegador | Carregar via next/dynamic com { ssr: false } |
Como resolver o erro de hidratação passo a passo
Análises detalhadas do problema, como o artigo técnico publicado no blog da OneUptime, reforçam que existem abordagens específicas para cada causa de desalinhamento. A seguir estão os passos práticos para corrigir cada cenário.
Passo 1: Ajustar o código que depende do cliente com useEffect
Para trechos de código que dependem de window ou localStorage, utilize o hook useEffect. O servidor renderizará o estado inicial seguro e, após a hidratação, o React atualizará a tela no cliente.
'use client';
import { useState, useEffect } from 'react';
export default function UserProfile() {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
if (!isClient) {
return <div>Carregando...</div>;
}
const theme = localStorage.getItem('theme');
return <div>Tema atual: {theme}</div>;
}
Passo 2: Desabilitar o SSR em componentes específicos com next/dynamic
Se você possui um componente que depende inteiramente de APIs do navegador e não precisa ser pré-renderizado no servidor, desabilite o SSR (Server-Side Rendering) utilizando a função dynamic do next/dynamic.
import dynamic from 'next/dynamic';
const ComponenteApenasCliente = dynamic(
() => import('../components/ApenasCliente'),
{ ssr: false }
);
export default function Page() {
return (
<main>
<h1>Minha Página</h1>
<ComponenteApenasCliente />
</main>
);
}
Passo 3: Garantir consistência em datas e fusos horários
Para evitar divergências de data entre o servidor (que pode operar em UTC) e o cliente (no fuso de São Paulo), defina explicitamente as opções de fuso horário utilizando Intl.DateTimeFormat ou formate a string diretamente no servidor sem recalculá-la no navegador.
export default function DataFormatada({ date }: { date: Date }) {
const dataFormatada = new Intl.DateTimeFormat('pt-BR', {
dateStyle: 'full',
timeStyle: 'medium',
timeZone: 'America/Sao_Paulo',
}).format(date);
return <time>{dataFormatada}</time>;
}

Passo 4: Bloquear a auto-formatação do iOS com meta tag
Para impedir que o iOS insira tags de link automáticas em números e e-mails no texto, adicione a meta tag format-detection no seu arquivo de layout ou cabeçalho da aplicação.
export const metadata = {
other: {
'format-detection': 'telephone=no, date=no, email=no, address=no',
},
};
Em HTML tradicional ou páginas legadas, a tag corresponde ao seguinte formato:
<meta name="format-detection" content="telephone=no, date=no, email=no, address=no" />
Passo 5: Usar a prop suppressHydrationWarning de forma consciente
A documentação do Next.js disponibiliza a propriedade suppressHydrationWarning para indicar ao React que ele não deve avisar sobre divergências em um elemento específico. Ela é útil para timestamps que mudam rapidamente, mas deve ser usada com atenção devido às suas três ressalvas explícitas:
- Funciona apenas um nível de profundidade no elemento em que foi aplicada.
- É uma escape hatch (mecanismo de fuga) que não deve ser usada em excesso no código.
- O React não tenta corrigir o conteúdo de texto divergente quando a propriedade está ativa, mantendo o valor do servidor visível até outra atualização.
export default function Timestamp() {
return (
<span suppressHydrationWarning>
{new Date().toLocaleTimeString()}
</span>
);
}
Perguntas frequentes
Por que espalhar suppressHydrationWarning pelo código é uma má prática?
Porque a prop suppressHydrationWarning funciona apenas como uma trava de aviso e não corrige a causa raiz da divergência. Além disso, ela atua apenas em um nível de profundidade e faz com que o React ignore discrepâncias no texto, o que pode mascarar bugs visuais sérios na aplicação.
Como o Cloudflare Auto Minify afeta a hidratação no Next.js?
O recurso Auto Minify da Cloudflare modifica o código HTML enviado pelo servidor antes que ele chegue ao navegador do cliente. Como o React no cliente espera receber exatamente a mesma estrutura HTML que gerou no servidor, essa alteração externa provoca uma falha de correspondência durante a hidratação.
O que acontece se eu renderizar o construtor Date() direto no JSX?
Como a execução ocorre em momentos e locais diferentes, o servidor vai gerar uma string de data baseada no horário da requisição e no fuso do servidor, enquanto o cliente vai gerar outra string baseada no relógio do computador do usuário. Essa diferença de texto entre o HTML do servidor e o do cliente quebra o processo de hidratação do React.
Conclusão
Resolver o erro de hidratação no Next.js exige entender a origem da discrepância em vez de simplesmente ocultar o aviso. Ao identificar erros de aninhamento HTML, isolar código do cliente com useEffect, fixar fusos horários em datas e desativar modificadores do iOS, sua aplicação em Next.js alcança estabilidade e alta performance em produção.

Sobre a Lee Sugano
Lee Sugano
Agência de soluções digitais com base no Japão e clientes em mais de 10 países. Compartilhamos insights sobre desenvolvimento, design e marketing digital para empresas que não aceitam genérico.
Gostou deste conteúdo?
Receba insights exclusivos sobre desenvolvimento web, design e marketing digital diretamente no seu email.
Sem spam. Cancele quando quiser.


