Autor:
    Criação:2026-09-02Última atualização:2026-09-02

    O next-intl está obsoleto em 2026?

    Quando a Vercel apresentou o App Router e descontinuou a i18n nativa do Pages Router, o next-intl supriu a carência rapidamente. Jan Amann ofereceu documentação exemplar e suporte pontual ao App Router, transformando a biblioteca na escolha comum da comunidade.

    Por qual razão, então, reavaliar sua adequação hoje?

    A arquitetura web progrediu significativamente nos últimos três anos, mas a base do next-intl permaneceu estática.

    Enquanto o Next.js evoluiu em direção aos React Server Components (RSC), ao streaming e a otimizações por compilador, o next-intl ainda trata a internacionalização como uma responsabilidade de execução: enviando volumosos objetos JSON por provedores cliente, executando formatadores ICU nos navegadores e dependendo da triagem manual de namespaces para conter o crescimento do pacote.

    Principais conclusões

    Ritmo de desenvolvimento estabilizado:

    Nos últimos 12 meses, o next-intl somou ~187 commits, focados quase que integralmente em compatibilidade com o Next.js e correções menores.

    Custo de execução no cliente:

    Montar o NextIntlClientProvider com useTranslations() adiciona ~12.8 KB gzipped (51 KB minificados) antes de exibir qualquer texto, quase o triplo do next-intlayer (4.3 KB).

    Vazamento de conteúdo de 90%:

    Em arranjos comuns, 89.8% do payload de traduções recebido por uma página pertence a outras rotas. Acessar /contact força o download de textos de /pricing e /dashboard.

    Gestão manual de namespaces:

    Prevenir o inchaço dos pacotes requer fragmentar e mapear namespaces rota por rota manualmente, ampliando a possibilidade de falhas em produção.

    Parceria comercial:

    Como parceiro oficial do Crowdin, o projeto tem poucos motivos para priorizar um comando gratuito de tradução por IA local em sua CLI.

    Manutenção vs. ferramentas atuais

    Atividade de commits ao longo dos últimos doze meses:

    Repositório Estrelas Total de commits Commits / ano Último commit
    amannn/next-intl stars commits yearly last
    aymericzip/intlayer stars commits yearly last

    Histórico recente:

    • amannn/next-intl: 187 commits (ajustes de compatibilidade e pequenos reparos).
    • aymericzip/intlayer: 4.343 commits (evolução ativa em compiladores, extensões de editor, servidores MCP e motores de tradução).

    Star History Chart

    Uma ferramenta consolidada pode ser confiável. Mas o ecossistema de i18n se modernizou: compiladores removem conteúdo sem referência em tempo de build, LLMs automatizam a tradução em CI e editores se integram com Language Servers (LSP) e agentes de IA. Uma arquitetura restrita ao runtime não usufrui plenamente desses avanços.

    Avaliação no Next.js 16 App Router

    Benchmark conduzido em uma aplicação App Router padrão com 10 rotas e 10 idiomas:

    Carregamento JSON dinâmico

    Carrega as traduções tardiamente em tempo de execução

    JSON com escopo (namespacing)

    Namespaces de tradução por página

    Benchmark de Desempenho I18n

    O que é essa métrica?

    O tamanho total compactado em gzip do pacote da biblioteca de internacionalização. Inclui apenas o provedor e a lógica de recuperação de conteúdo após o tree-shaking e a minificação.

    Por que é importante?

    Um tamanho de biblioteca menor reduz a carga útil inicial de JavaScript, resultando em tempos de download e execução mais rápidos no cliente.

    Ver como

    Avaliado em navegadores reais com compressão gzip de produção. Informações completas no relatório de benchmark Next.js.

    Pegada base da biblioteca

    Peso no cliente antes de acrescentar quaisquer textos:

    Biblioteca Gzipped Minificado
    next-intl@4.9.1 12.8 KB 51.0 KB
    next-intlayer@8.7.12 4.3 KB 13.3 KB

    Peso da página e vazamento de dados

    Configuração JS médio / pág (gz) Vazamento idioma Vazamento outras págs Componente médio (gz)
    Base (sem i18n) 150.8 KB 0.0% 0.0% 0.7 KB
    next-intl (estático) 163.5 KB 4.2% 89.8% 20.5 KB
    next-intl (dinâmico) 163.4 KB 9.7% 89.9% 20.5 KB
    next-intlayer 152.1 KB 0.0% 0.0% 7.2 KB

    Como ocorre o vazamento entre rotas

    Em implementações habituais do next-intl, o layout raiz carrega todos os textos de uma única vez:

    app/[locale]/layout.tsx
    export default async function RootLayout({ children, params }) {
      const messages = await getMessages();
    
      return (
        <html>
          <body>
            <NextIntlClientProvider messages={messages}>
              {children}
            </NextIntlClientProvider>
          </body>
        </html>
      );
    }
    

    Ao fornecer messages ao provedor na raiz, o navegador baixa a coleção integral de mensagens em qualquer página. Quem visita /login é obrigado a carregar também as seções de ajuda, termos e dashboards.

    É possível atenuar o problema dividindo arquivos JSON por namespaces. Contudo, manter essa tabela manualmente demanda esforço contínuo e gera erros frequentes.

    O Intlayer soluciona isso por análise estática: o compilador do Intlayer empacota exclusivamente os textos solicitados por cada rota, reduzindo o vazamento para 0.0%.

    Por que o next-intl não suporta tree-shaking

    Sua API depende de buscas dinâmicas por strings em runtime:

    UserProfile.tsx
    "use client";
    
    import { useTranslations } from "next-intl";
    
    export function UserProfile() {
      const t = useTranslations("UserProfile");
    
      return <h2>{t("heading")}</h2>;
    }
    
    UserProfile.tsx
    "use client";
    
    import { useIntlayer } from "next-intlayer";
    
    export function UserProfile() {
      const { heading } = useIntlayer("user-profile");
    
      return <h2>{heading}</h2>;
    }
    

    Turbopack e Webpack não conseguem assegurar quais chaves de UserProfile serão de fato invocadas. Para não ocasionar erros, o bundler precisa empacotar o namespace por inteiro no bundle do cliente. A desestruturação do Intlayer permite ao compilador inspecionar referências concretas e suprimir campos sem utilidade. Saiba mais em otimização de bundle.

    Experiência do desenvolvedor

    JSON segregado vs. co-localização

    Com o next-intl, os textos ficam retidos em pastas messages/ distantes do código. O Intlayer reúne as declarações de conteúdo junto aos componentes:

    messages/en.json
    {
      "authModal": {
        "title": "Sign in to your account",
        "submitButton": "Continue"
      }
    }
    
    messages/pt.json
    {
      "authModal": {
        "title": "Entre na sua conta",
        "submitButton": "Continuar"
      }
    }
    
    AuthModal.tsx
    import { useTranslations } from "next-intl";
    
    export const AuthModal = () => {
      const t = useTranslations("authModal");
      return (
        <form>
          <h2>{t("title")}</h2>
          <button type="submit">{t("submitButton")}</button>
        </form>
      );
    };
    
    AuthModal.content.ts
    import { t, type Dictionary } from "intlayer";
    
    export default {
      key: "auth-modal",
      content: {
        title: t({
          en: "Sign in to your account",
          pt: "Entre na sua conta",
        }),
        submitButton: t({
          en: "Continue",
          pt: "Continuar",
        }),
      },
    } satisfies Dictionary;
    
    AuthModal.tsx
    import { useIntlayer } from "next-intlayer";
    
    export const AuthModal = () => {
      const { title, submitButton } = useIntlayer("auth-modal");
      return (
        <form>
          <h2>{title}</h2>
          <button type="submit">{submitButton}</button>
        </form>
      );
    };
    

    Ao mover ou remover AuthModal.tsx, as traduções associadas são ajustadas ou excluídas em conjunto.

    Sugestão de código vs. segurança estrita de tipos

    Definir IntlMessages no next-intl traz autocompletar baseado no arquivo de idioma principal:

    global.d.ts
    import en from "./messages/en.json";
    
    type Messages = typeof en;
    
    declare global {
      interface IntlMessages extends Messages {}
    }
    

    Entretanto, apenas o idioma base é verificado. Se uma chave for excluída de pt.json, o TypeScript não emitirá avisos, seu build passará normalmente e os usuários receberão textos ausentes.

    O Intlayer infere tipos a partir de todas as declarações. Com o strictMode, traduções incompletas geram erros imediatos na compilação.

    Ecossistema e automação com IA

    Funcionalidade next-intl Intlayer
    Extensão VS Code ❌ Nenhuma Extensão oficial
    Language Server (LSP) ❌ Nenhum LSP dedicado
    Servidor MCP (para agentes) ❌ Nenhum Servidor MCP integrado
    Habilidades de Agente ❌ Nenhuma Skills prontas
    CMS Visual em contexto ❌ Nenhum Gratuito & Open Source

    A presença de servidores LSP e MCP viabiliza que assistentes de codificação entendam a estrutura de conteúdo do projeto e sugiram atualizações com alta precisão.

    A relação com o Crowdin

    O next-intl conta com patrocínio oficial do Crowdin. Apoios financeiros são importantes para o software livre, mas direcionam prioridades: estruturado para operar como cliente de serviços TMS externos, o next-intl não prioriza ferramentas gratuitas e locais de tradução por IA na CLI.

    O Intlayer disponibiliza esses recursos nativamente:

    Preenchimento automático por IA local (intlayer fill):

    Localiza e traduz textos ausentes utilizando suas credenciais da OpenAI, Anthropic, Mistral ou Gemini.

    CMS visual auto-hospedado:

    Use o CMS Intlayer para capacitar editores a ajustarem textos com gravação direta no Git.

    Licença de código aberto permissiva:

    Todo o pacote opera sob licença Apache 2.0.

    Em quais situações o next-intl ainda é aplicável?

    Se o sistema utiliza extensivamente seletores ordinais encadeados e formatos avançados, o suporte a ICU do next-intl é confiável.

    Para times cujo processo de tradução já se apoia integralmente no Crowdin, a integração do next-intl é bastante fluida.

    Se a aplicação atende bem aos requisitos e o tamanho do pacote não afeta o desempenho esperado, a migração não se faz urgente.

    Como melhorar minha configuração atual do next-intl?

    O Intlayer fornece um pacote de compatibilidade direta que replica as assinaturas de funções e hooks do next-intl (como useTranslations, getTranslations e auxiliares de navegação). Você não precisa reescrever componentes para obter as vantagens de otimização em nível de compilador.

    A configuração é feita com um único comando:

    bash
    npx intlayer init --interactive
    

    Essa CLI interativa:

    1. Instala o pacote de compatibilidade @intlayer/next-intl.
    2. Configura aliases no empacotador para que suas importações (next-intl, next-intl/server) apontem para o Intlayer, permitindo desinstalar a biblioteca antiga do package.json.
    3. Ativa imediatamente o Language Server (LSP), a eliminação de vazamentos de dados entre páginas (tree-shaking completo) e fluxos locais de tradução por IA sem necessidade de uma refatoração pesada.

    Para instruções detalhadas, veja nossos guias dedicados:

    Avalie o payload e vazamento do seu site com o scanner de SEO para i18n gratuito:

    Leituras complementares

    Comentários

    Ainda sem comentários. Seja o primeiro a compartilhar seus pensamentos.

    Artigos relacionados

    Últimos artigos