Next.js Internacionalização (i18n) com next-intl e Intlayer

    Tanto o next-intl quanto o Intlayer são frameworks de internacionalização (i18n) de código aberto projetados para aplicações Next.js. Eles são amplamente utilizados para gerenciar traduções, localização e troca de idiomas em projetos de software.

    Eles compartilham três noções principais:

    1. Declaração de Conteúdo: O método para definir o conteúdo traduzível da sua aplicação.

      • Chamado de arquivo de declaração de conteúdo no Intlayer, que pode ser um arquivo JSON, JS ou TS exportando os dados estruturados. Veja documentação do Intlayer para mais informações.
      • Chamado de messages ou locale messages no next-intl, geralmente em arquivos JSON. Veja documentação do next-intl para mais informações.
    2. Utilitários: Ferramentas para construir e interpretar declarações de conteúdo na aplicação, como useIntlayer() ou useLocale() para Intlayer, e useTranslations() para next-intl.

    3. Plugins e Middlewares: Recursos para gerenciar redirecionamento de URL, otimização de empacotamento, e mais—ex: intlayerMiddleware para Intlayer ou createMiddleware para next-intl.

    Intlayer vs. next-intl: Principais Diferenças

    Para uma análise mais profunda de como o Intlayer se compara a outras bibliotecas de i18n para Next.js (como o next-intl), confira o post no blog next-i18next vs. next-intl vs. Intlayer.

    Como Gerar Mensagens next-intl com Intlayer

    Por que Usar Intlayer com next-intl?

    Os arquivos de declaração de conteúdo do Intlayer geralmente oferecem uma melhor experiência para o desenvolvedor. Eles são mais flexíveis e manuteníveis devido a duas principais vantagens:

    1. Colocação Flexível: Você pode colocar um arquivo de declaração de conteúdo do Intlayer em qualquer lugar na árvore de arquivos da sua aplicação. Isso facilita renomear ou deletar componentes sem deixar arquivos de mensagem não utilizados ou pendentes.

      Exemplos de estruturas de arquivos:

      bash
      .└── src    └── components        └── MyComponent            ├── index.content.ts # Arquivo de declaração de conteúdo            └── index.tsx
    2. Traduções Centralizadas: O Intlayer armazena todas as traduções em uma única declaração de conteúdo, garantindo que nenhuma tradução esteja faltando. Em projetos TypeScript, traduções ausentes são sinalizadas automaticamente como erros de tipo, fornecendo feedback imediato aos desenvolvedores.

    Instalação

    Para usar o Intlayer e o next-intl juntos, instale ambas as bibliotecas:

    bash
    npm install intlayer next-intl

    Configurando o Intlayer para Exportar Mensagens next-intl

    Nota: Exportar mensagens do Intlayer para o next-intl pode introduzir pequenas diferenças na estrutura. Se possível, mantenha um fluxo apenas do Intlayer ou apenas do next-intl para simplificar a integração. Se você precisar gerar mensagens next-intl a partir do Intlayer, siga os passos abaixo.

    Crie ou atualize um arquivo intlayer.config.ts (ou .mjs / .cjs) na raiz do seu projeto:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],    defaultLocale: Locales.ENGLISH,  },  content: {    dictionaryOutput: ["next-intl"], // Usar a saída do next-intl    nextIntlMessagesDir: "./intl/messages", // Onde salvar mensagens next-intl  },};export default config;

    Declaração de Conteúdo

    Abaixo estão exemplos de arquivos de declaração de conteúdo em múltiplos formatos. O Intlayer compilará isso em arquivos de mensagem que o next-intl pode consumir.

    **/*.content.ts
    import { t, type DeclarationContent } from "intlayer";const content = {  key: "my-component",  content: {    helloWorld: t({      en: "Hello World",      fr: "Bonjour le monde",      es: "Hola Mundo",    }),  },} satisfies DeclarationContent;export default content;

    Construir as Mensagens next-intl

    Para construir os arquivos de mensagem para o next-intl, execute:

    bash
    npx intlayer build

    Isso irá gerar recursos no diretório ./intl/messages (conforme configurado em intlayer.config.*). A saída esperada:

    bash
    .└── intl    └── messages       └── pt           └── my-content.json       └── fr           └── my-content.json       └── es           └── my-content.json

    Cada arquivo inclui mensagens compiladas de todas as declarações de conteúdo do Intlayer. As chaves de nível superior normalmente correspondem aos seus campos content.key.

    Usando next-intl em Seu App Next.js

    Para mais detalhes, veja a documentação oficial de uso do next-intl.

    1. Criar um Middleware (opcional):
      Se você quiser gerenciar a detecção automática de idioma ou redirecionamento, use o createMiddleware do next-intl.

      middleware.ts
      import createMiddleware from "next-intl/middleware";import { NextResponse } from "next/server";export default createMiddleware({  locales: ["en", "fr", "es"],  defaultLocale: "en",});export const config = {  matcher: ["/((?!api|_next|.*\\..*).*)"],};
    2. Criar um layout.tsx ou _app.tsx para Carregar Mensagens:
      Se você está usando o App Router (Next.js 13+), crie um layout:

      app/[locale]/layout.tsx
      import { NextIntlClientProvider } from 'next-intl';import { notFound } from 'next/navigation';import React, { ReactNode } from 'react';export const dynamic = 'force-dynamic';export default async function RootLayout({  children,  params}: {  children: ReactNode;  params: { locale: string };}) {  let messages;  try {    messages = (await import(`../../intl/messages/${params.locale}.json`)).default;  } catch (error) {    notFound();  }  return (    <html lang={params.locale}>      <body>

    Se você tiver uma ideia para melhorar esta blogumentação, sinta-se à vontade para contribuir enviando uma pull request no GitHub.

    Link do GitHub para o blog