1. Documentation
    2. Ambiente
    3. Intlayer com Vite e React

    Começando a Internacionalização (i18n) com Intlayer, Vite e React

    O que é Intlayer?

    Intlayer é uma biblioteca inovadora de internacionalização (i18n), de código aberto, projetada para simplificar o suporte a múltiplos idiomas em aplicações web modernas.

    Com o Intlayer, você pode:

    • Gerenciar traduções facilmente utilizando dicionários declarativos no nível do componente.
    • Localizar dinamicamente metadados, rotas e conteúdo.
    • Garantir suporte TypeScript com tipos gerados automaticamente, melhorando a autocompletação e a detecção de erros.
    • Beneficiar-se de recursos avançados, como detecção e mudança dinâmica de localidade.

    Guia Passo a Passo para Configurar Intlayer em uma Aplicação Vite e React

    Passo 1: Instalar Dependências

    Instale os pacotes necessários usando npm:

    bash
    1npm install intlayer react-intlayer
    bash
    1yarn add intlayer react-intlayer
    bash
    1pnpm add intlayer react-intlayer

    Passo 2: Configuração do seu projeto

    Crie um arquivo de configuração para configurar os idiomas da sua aplicação:

    typescript
    1// intlayer.config.ts 2 3import { Locales, type IntlayerConfig } from "intlayer"; 4 5const config: IntlayerConfig = { 6 internationalization: { 7 locales: [ 8 Locales.PORTUGUESE, 9 Locales.FRENCH, 10 Locales.SPANISH, 11 // Seus outros idiomas 12 ], 13 defaultLocale: Locales.PORTUGUESE, 14 }, 15}; 16 17export default config;

    Para ver todos os parâmetros disponíveis, consulte a documentação de configuração aqui.

    Passo 3: Integrar Intlayer na sua Configuração Vite

    Adicione o plugin intlayer na sua configuração.

    typescript
    1import { defineConfig } from "vite"; 2import react from "@vitejs/plugin-react-swc"; 3import { intLayerPlugin } from "react-intlayer/vite"; 4 5// https://vitejs.dev/config/ 6export default defineConfig({ 7 plugins: [react(), intLayerPlugin()], 8});

    Passo 4: Declare Seu Conteúdo

    Crie e gerencie seus dicionários de conteúdo:

    tsx
    1// src/app.content.tsx 2import { t, type DeclarationContent } from "intlayer"; 3import { type ReactNode } from "react"; 4 5const appContent = { 6 key: "app", 7 content: { 8 viteLogo: t({ 9 en: "Vite logo", 10 fr: "Logo Vite", 11 es: "Logo Vite", 12 }), 13 reactLogo: t({ 14 en: "React logo", 15 fr: "Logo React", 16 es: "Logo React", 17 }), 18 19 title: "Vite + React", 20 21 count: t({ 22 en: "count is ", 23 fr: "le compte est ", 24 es: "el recuento es ", 25 }), 26 27 edit: t<ReactNode>({ 28 // Não se esqueça de importar React se você usar um nó React em seu conteúdo 29 en: ( 30 <> 31 Edit <code>src/App.tsx</code> and save to test HMR 32 </> 33 ), 34 fr: ( 35 <> 36 Éditez <code>src/App.tsx</code> et enregistrez pour tester HMR 37 </> 38 ), 39 es: ( 40 <> 41 Edita <code>src/App.tsx</code> y guarda para probar HMR 42 </> 43 ), 44 }), 45 46 readTheDocs: t({ 47 en: "Click on the Vite and React logos to learn more", 48 fr: "Cliquez sur les logos Vite et React pour en savoir plus", 49 es: "Haga clic en los logotipos de Vite y React para obtener más información", 50 }), 51 }, 52} satisfies DeclarationContent; 53 54export default appContent;

    Nota: Se seu arquivo de conteúdo incluir código TSX, você deve considerar importar import React from "react"; em seu arquivo de conteúdo.

    Veja como declarar seus arquivos de declaração do Intlayer.

    Passo 5: Utilize Intlayer no Seu Código

    Acesse seus dicionários de conteúdo em toda a sua aplicação:

    tsx
    1import { useState } from "react"; 2import reactLogo from "./assets/react.svg"; 3import viteLogo from "/vite.svg"; 4import "./App.css"; 5import { LocaleSwitcher } from "./components/LangSwitcherDropDown"; 6import { IntlayerProvider, useIntlayer } from "react-intlayer"; 7 8function AppContent() { 9 const [count, setCount] = useState(0); 10 const content = useIntlayer("app"); 11 12 return ( 13 <> 14 <div> 15 <a href="https://vitejs.dev" target="_blank"> 16 <img src={viteLogo} className="logo" alt={content.viteLogo.value} /> 17 </a> 18 <a href="https://react.dev" target="_blank"> 19 <img 20 src={reactLogo} 21 className="logo react" 22 alt={content.reactLogo.value} 23 /> 24 </a> 25 </div> 26 <h1>{content.title}</h1> 27 <div className="card"> 28 <button onClick={() => setCount((count) => count + 1)}> 29 {content.count} 30 {count} 31 </button> 32 <p>{content.edit}</p> 33 </div> 34 <p className="read-the-docs">{content.readTheDocs}</p> 35 <div className="absolute bottom-5 right-5 z-50"> 36 <LocaleSwitcher /> 37 </div> 38 </> 39 ); 40} 41 42function App() { 43 return ( 44 <IntlayerProvider> 45 <AppContent /> 46 </IntlayerProvider> 47 ); 48} 49 50export default App;

    Nota: Se você quiser usar seu conteúdo em um atributo string, como alt, title, href, aria-label, etc., você deve chamar o valor da função, como:

    tsx
    1<img src={content.image.src.value} alt={content.image.value} />

    (Opcional) Passo 6: Mudar o idioma do seu conteúdo

    Para mudar o idioma do seu conteúdo, você pode usar a função setLocale fornecida pelo hook useLocale. Esta função permite que você defina a localidade da aplicação e atualize o conteúdo de acordo.

    tsx
    1import { Locales } from "intlayer"; 2import { useLocale } from "react-intlayer"; 3 4const LocaleSwitcher = () => { 5 const { setLocale } = useLocale(); 6 7 return ( 8 <button onClick={() => setLocale(Locales.PORTUGUESE)}> 9 Mudar idioma para Português 10 </button> 11 ); 12};

    (Opcional) Passo 7: Adicionar Roteamento Localizado à sua aplicação

    O objetivo deste passo é criar rotas únicas para cada idioma. Isso é útil para SEO e URLs amigáveis. Exemplo:

    tsx
    1// /painel 2// /es/painel 3// /fr/painel

    Por padrão, as rotas não são prefixadas para a localidade padrão. Se você quiser prefixar a localidade padrão, pode definir a opção middleware.prefixDefault como true em sua configuração. Consulte a documentação de configuração para mais informações.

    Para adicionar roteamento localizado à sua aplicação, você pode criar um componente LocaleRouter que encapsula as rotas da sua aplicação e lida com o roteamento baseado na localidade. Aqui está um exemplo usando React Router:

    tsx
    1// Importando dependências e funções necessárias 2import { Locales, getConfiguration, getPathWithoutLocale } from "intlayer"; // Funções e tipos utilitários de 'intlayer' 3import { FC, PropsWithChildren } from "react"; // Tipos React para componentes funcionais e props 4import { IntlayerProvider } from "react-intlayer"; // Provedor para contexto de internacionalização 5import { 6 BrowserRouter, 7 Routes, 8 Route, 9 useParams, 10 Navigate, 11 useLocation, 12} from "react-router-dom"; // Componentes Router para gerenciar navegação 13 14// Desestruturando a configuração do Intlayer 15const { internationalization, middleware } = getConfiguration(); 16const { locales, defaultLocale } = internationalization; 17 18/** 19 * Um componente que lida com localização e encapsula os filhos com o contexto de localidade apropriado. 20 * Ele gerencia a detecção e validação de URL com base na localidade. 21 */ 22const AppLocalized: FC<PropsWithChildren> = ({ children }) => { 23 const path = useLocation().pathname; // Obtém o caminho da URL atual 24 const { locale } = useParams<{ locale: Locales }>(); // Extrai o parâmetro de localidade da URL 25 26 // Determina a localidade atual, retornando à padrão se não fornecido 27 const currentLocale = locale ?? defaultLocale; 28 29 // Remove o prefixo de localidade do caminho para construir um caminho base 30 const pathWithoutLocale = getPathWithoutLocale( 31 path // Caminho da URL atual 32 ); 33 34 /** 35 * Se middleware.prefixDefault for verdadeiro, a localidade padrão deve sempre ser prefixada. 36 */ 37 if (middleware.prefixDefault) { 38 // Valida a localidade 39 if (!locale || !locales.includes(locale)) { 40 // Redireciona para a localidade padrão com o caminho atualizado 41 return ( 42 <Navigate 43 to={`/${defaultLocale}/${pathWithoutLocale}`} 44 replace // Substituir a entrada de histórico atual pela nova 45 /> 46 ); 47 } 48 49 // Encapsula os filhos com o IntlayerProvider e define a localidade atual 50 return ( 51 <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider> 52 ); 53 } else { 54 /** 55 * Quando middleware.prefixDefault é falso, a localidade padrão não é prefixada. 56 * Garante que a localidade atual seja válida e não a localidade padrão. 57 */ 58 if ( 59 currentLocale.toString() !== defaultLocale.toString() && 60 !locales 61 .filter( 62 (locale) => locale.toString() !== defaultLocale.toString() // Exclui a localidade padrão 63 ) 64 .includes(currentLocale) // Verifica se a localidade atual está na lista de localidades válidas 65 ) { 66 // Redireciona para o caminho sem o prefixo da localidade 67 return <Navigate to={pathWithoutLocale} replace />; 68 } 69 70 // Encapsula os filhos com o IntlayerProvider e define a localidade atual 71 return ( 72 <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider> 73 ); 74 } 75}; 76 77/** 78 * Um componente de roteador que configura rotas específicas de localidade. 79 * Utiliza o React Router para gerenciar navegação e renderizar componentes localizados. 80 */ 81export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => ( 82 <BrowserRouter> 83 <Routes> 84 <Route 85 // Padrão da rota para capturar a localidade (por exemplo, /pt/, /fr/) e combinar todos os caminhos subsequentes 86 path="/:locale/*" 87 element={<AppLocalized>{children}</AppLocalized>} // Encapsula filhos com gerenciamento de localidade 88 /> 89 90 { 91 // Se o prefixo da localidade padrão estiver desativado, renderiza os filhos diretamente no caminho raiz 92 !middleware.prefixDefault && ( 93 <Route 94 path="*" 95 element={<AppLocalized>{children}</AppLocalized>} // Encapsula filhos com gerenciamento de localidade 96 /> 97 ) 98 } 99 </Routes> 100 </BrowserRouter> 101);

    Em paralelo, você também pode usar o intLayerMiddlewarePlugin para adicionar roteamento do lado do servidor à sua aplicação. Este plugin irá detectar automaticamente a localidade atual com base na URL e definir o cookie de localidade apropriado. Se nenhuma localidade for especificada, o plugin determinará a localidade mais apropriada com base nas preferências de idioma do navegador do usuário. Se nenhuma localidade for detectada, ele redirecionará para a localidade padrão.

    ts
    1import { defineConfig } from "vite"; 2import react from "@vitejs/plugin-react-swc"; 3import { intLayerPlugin, intLayerMiddlewarePlugin } from "react-intlayer/vite"; 4 5// https://vitejs.dev/config/ 6export default defineConfig({ 7 plugins: [react(), intLayerPlugin(), intLayerMiddlewarePlugin()], 8});

    (Opcional) Passo 8: Mudar a URL quando a localidade mudar

    Para mudar a URL quando a localidade mudar, você pode usar a prop onLocaleChange fornecida pelo hook useLocale. Em paralelo, você pode usar os hooks useLocation e useNavigate do react-router-dom para atualizar o caminho da URL.

    tsx
    1import { Locales, getLocalizedUrl } from "intlayer"; 2import { useLocale } from "react-intlayer"; 3import { useLocation, useNavigate } from "react-router-dom"; 4 5const LocaleSwitcher = () => { 6 const location = useLocation(); // Obtém o caminho da URL atual. Exemplo: /fr/sobre 7 const navigate = useNavigate(); 8 9 const changeUrl = (locale: Locales) => { 10 // Constrói a URL com a localidade atualizada 11 // Exemplo: /es/sobre com a localidade definida para espanhol 12 const pathWithLocale = getLocalizedUrl(location.pathname, locale); 13 14 // Atualiza o caminho da URL 15 navigate(pathWithLocale); 16 }; 17 18 const { setLocale } = useLocale({ 19 onLocaleChange: changeUrl, 20 }); 21 22 return ( 23 <button onClick={() => setLocale(Locales.PORTUGUESE)}> 24 Mudar idioma para Português 25 </button> 26 ); 27};

    Configurar TypeScript

    Intlayer usa aumento de módulo para obter benefícios do TypeScript e tornar seu código mais forte.

    alt text

    alt text

    Certifique-se de que sua configuração TypeScript inclua os tipos gerados automaticamente.

    json5
    1// tsconfig.json 2 3{ 4 // sua configuração personalizada 5 include: [ 6 "src", 7 "types", // <- Inclua os tipos gerados automaticamente 8 ], 9}

    Configuração do Git

    É recomendável ignorar os arquivos gerados pelo Intlayer. Isso permite que você evite contabilizá-los em seu repositório Git.

    Para fazer isso, você pode adicionar as seguintes instruções ao seu arquivo .gitignore:

    gitignore
    1# Ignore os arquivos gerados pelo Intlayer 2.intlayer

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

    Link do GitHub para a documentação

    Nesta página