Como as principais bibliotecas de front-end lidam com i18n
Uma forma de as empresas alcançarem novos clientes é falar a língua deles. Para fazer isso, os desenvolvedores precisam usar a internacionalização e a localização em seus aplicativos para oferecer produtos e conteúdo nos idiomas nativos dos usuários.
Internacionalização, ou i18n (18 é o número de letras entre i e n), é o processo de construção de seu produto para suportar vários idiomas. Isso pode incluir separar o texto do código e usar uma biblioteca para formatar datas com base em diferentes países e fusos horários. Quando seu produto estiver pronto para adicionar suporte para idiomas específicos, você poderá passar para a localização.
Localização, ou l10n, é o processo de adicionar suporte para uma região, país ou idioma específico. Isso é diferente de traduzir texto para outro idioma, embora a localização possa incluir tradução. Aqui estão algumas coisas que você deve ter em mente ao localizar um produto:
- Formatação de data, como DD/MM/AAAA vs. MM/DD/AAAA
- Formatação de nomes, já que em alguns países os sobrenomes são exibidos antes dos nomes
- Moeda
- Medições (sistema imperial vs. sistema métrico)
As imagens também devem ser adaptadas a um determinado mercado, especialmente aquelas que exibem texto.
Lembre-se de que um CMS headless pode ajudá-lo a obter localização facilmente. Strapi, o CMS headless de código aberto líder com uma comunidade de mais de 135.000 usuários, oferece soluções personalizáveis para gerenciar e localizar seu conteúdo.
Em menos de uma hora, você pode usar o Strapi para ter endpoints de API e um painel de administração prontos para uso. Com GraphQL ou Rest, você pode consumir qualquer endpoint da API Strapi de qualquer cliente (Vue, React ou Angular, por exemplo), o que lhe dá grande flexibilidade.
Conteudo
Flutter
Criada pelo Google em 2017, Flutter é uma biblioteca que está ganhando força rapidamente. Como esperado de uma empresa global como o Google, a internacionalização faz parte da biblioteca e pode ser implementada quase instantaneamente.
O Flutter suporta não apenas texto traduzido, mas também plurais, formatação de números e datas e texto da direita para a esquerda ou da esquerda para a direita. Isso o torna uma escolha sólida para desenvolvedores.
Internacionalize seu aplicativo Flutter
Para começar, atualize seu pubspec.yaml
. Adicione generate true
para gerar automaticamente os arquivos .dart
necessários para cada localidade que você adicionar.
# ... dependencies: flutter: sdk: flutter flutter_localizations: //Adicione esse sdk: flutter. // esse intl: ^0.18.1. // esse flutter: generate: true // e finalmente, este uses-material-design: true # ...
Execute flutter pub get
para obter os pacotes necessários.
Crie um arquivo l10n.yaml
em seu diretório raiz. Isso informa ao Flutter onde encontrar suas traduções e onde gerar os arquivos dart.
arb-dir: lib/l10n template-arb-file: app_en.arb output-localization-file: app_localizations.dart
Em seguida, crie um diretório I10n na sua pasta lib e crie seus arquivos de tradução. Aqui está um exemplo de arquivo app_en.arb
:
{ "appTitle": "Home Page" }
Em seu arquivo main.dart
, importe o pacote dart flutter_localizations
e adicione os delegados de localizações e os idiomas suportados. Usei inglês e francês aqui, mas é claro que você pode adicionar o seu próprio.
import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; // Nova importação return MaterialApp( title: 'Flutter Demo App', // Os pacotes Material, Cupertino e widgets agora serão localizados corretamente localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('en', ''), // English Locale('fr', ''), // French ], theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), );
Execute o aplicativo com flutter run
. Você deverá ver estes arquivos em sua ferramenta .dart-tool
:
- .dart_tool/flutter_gen/gen_l10n/app_localizations.dart
- .dart_tool/flutter_gen/gen_l10n/app_localizations_en.dart
- .dart_tool/flutter_gen/gen_l10n/app_localizations_fr.dart
Agora vamos adicionar nossa mensagem localizada.
import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; //Nosso arquivo gen_l10n recém-gerado import 'package:flutter_gen/gen_l10n/app_localizations.dart'; return MaterialApp( title: 'Localizations Sample App', localizationsDelegates: const [ AppLocalizations.delegate, // Novo delegado GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('en', ''), Locale('fr', ''), ], theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), );
Agora você pode acessar suas traduções através do AppLocalizations. Você poderia, por exemplo, passar um título para sua página inicial assim:
MyHomePage(title: AppLocalizations.of(context)!.appTitle)
Limitações do Flutter
O pacote de internacionalização tem poucas limitações, suportando muitos recursos necessários, como o tratamento de plurais ou texto bidirecional. Por ser uma linguagem muito nova, porém, o Flutter não possui a riqueza de pacotes de terceiros oferecidos com Ionic ou React. Além disso, o tamanho do pacote normalmente é maior que 4 MB.
Ionic
Mais antigo que o Flutter, o Ionic foi criado em 2013 e é uma biblioteca sólida que oferece aos desenvolvedores a capacidade de ter uma base de código para qualquer plataforma. Ionic oferece suporte para muitos frameworks, incluindo Angular, Vue e até mesmo React. Vou me concentrar no Angular aqui, pois o React será abordado abaixo.
Embora o Angular tenha um módulo de internacionalização integrado, a configuração é mais difícil para aplicativos Ionic. Como resultado, surgiram duas bibliotecas de terceiros:
Embora transloco seja mais recente e ofereça recursos como suporte SSR, ngx-translate é uma biblioteca sólida e confiável que existe há mais tempo e é adorada pelos desenvolvedores Angular. Usaremos ngx-translate como nossa biblioteca de tradução aqui.
Internacionalize seu aplicativo Ionic
Para começar, você precisará instalar a biblioteca necessária.
npm install @ngx-translate/core @ngx-translate/http-loader --save
Em seu src/app/assets
, adicione uma pasta i18n com suas traduções. Por exemplo, aqui está um arquivo en.json:
{ "title": "Welcome", "description": "This is an Ionic app translated by ngx-translate" }
Acesse app.module.ts e adicione seus módulos (TranslateModule, TranslateLoader, etc.). Isso informará ao seu aplicativo onde suas traduções estão localizadas e como carregá-las.
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { HttpClientModule, HttpClient } from '@angular/common/http'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; /* New function to load our translation files*/ export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, "./assets/i18n/", ".json"); } /* Add HttpClientModule & TranslateModule to our imports */ @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [HttpClientModule, BrowserModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }), , IonicModule.forRoot(), AppRoutingModule], providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }], bootstrap: [AppComponent], }) export class AppModule {}
Em app.component.ts
, defina seu idioma padrão.
import { Component } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'app-root', templateUrl: 'app.component.html', styleUrls: ['app.component.scss'], }) export class AppComponent { constructor(public translate: TranslateService) { this.initializeApp(); } initializeApp() { this.translate.addLangs(['en', 'fr']); this.translate.setDefaultLang('en'); } }
Finalmente, tente exibir algum texto traduzido.
<div id="container"> <strong>{{ 'title' | translate }} </strong> <p>{{ 'description' | translate }}</p> </div>
Limitações do Ionic
Existem aspectos específicos do Ionic que requerem algumas soluções alternativas.
Módulos e traduções de carregamento lento
Para módulos de carregamento lento, você também precisará importar módulos de tradução; caso contrário, a tradução não funcionará. Não se esqueça de usar forChild
em vez de forRoot
.
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IonicModule } from '@ionic/angular'; import { FormsModule } from '@angular/forms'; import { HomePage } from './home.page'; import { HomePageRoutingModule } from './home-routing.module'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { HttpClient } from '@angular/common/http'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; /* Once again, load your translations*/ export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, "./assets/i18n/", ".json"); } /* Add the translation module again, but this time, with forChild() */ @NgModule({ imports: [ TranslateModule.forChild({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }), CommonModule, FormsModule, IonicModule, HomePageRoutingModule ], declarations: [HomePage] }) export class HomePageModule {}
Pluralização e Gênero
A pluralização e a formatação de gênero não estão incluídas no ngx-translate. No entanto, existe um plugin para lidar com esses recursos e é reconhecido pela biblioteca oficial ngx-translate.
React
React precisa de pouca introdução. Criado pelo Facebook em 2013, rapidamente se tornou o favorito dos fãs de muitos desenvolvedores front-end.
Duas bibliotecas principais estão disponíveis para internacionalização no React:
- react-intl (agora chamado format.js)
- reagir-i18next
Embora ambos sejam populares (12.000 e 6.000 estrelas do GitHub, respectivamente), o react-i18next parece ter conquistado os desenvolvedores. Esta biblioteca tem a vantagem adicional de pertencer ao ecossistema i18next, um framework de tradução que oferece suporte para React, React Native e Electron, entre outros. Os desenvolvedores podem aprender uma vez e traduzi-lo facilmente em muitas estruturas diferentes.
Internacionalize seu aplicativo React
Para usar react-i18next, primeiro instale a biblioteca:
npm install react-i18next i18next --save
Na sua pasta src, ao lado do index.js
, crie um arquivo i18n.js
onde você adicionará suas traduções e conectará o react-i18next ao React.
import i18n from "i18next"; import { initReactI18next } from "react-i18next"; // Pro tip: Move them into their own JSON files const resources = { en: { translation: { "welcome_message": "Hello and Welcome to React" } }, fr: { translation: { "welcome_message": "Bonjour et bienvenue à React" } } }; i18n .use(initReactI18next) // Connect react-i18next to React .init({ resources, lng: "en", // default language interpolation: { escapeValue: false // react already safe from xss } }); export default i18n;
Em seguida, em seu index.js
, importe seu arquivo i18n.js
recém-criado:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import './i18n'; import App from './App'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
Você pode acessar sua tradução através, por exemplo, do useTranslationhook
.
import logo from './logo.svg'; import './App.css'; import { useTranslation } from 'react-i18next'; function App() { const { t } = useTranslation(); return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> {t('welcome_message')} </p> </header> </div> ); } export default App;
Limitações do React
A biblioteca é abrangente e cobre muitos recursos necessários. Plurais, interpolação, formatação, aninhamento e muito mais são tratados pelo react-i18next.
A única coisa um pouco complicada é traduzir texto com HTML. Por exemplo, “Olá, <i>{{nome}}</i>! Vá para sua <Link to=”/inbox”>caixa de entrada</Link> para ver suas novas mensagens”.
React-i18next lida com esse caso de uso transformando sua string em um nó de árvore e usando tags de substituição.
Sua string seria então dividida:
Trans.children = [ 'Hello, ', // 0: a string { name: ‘Marie’ }, // 1: <strong> with interpolation ‘! Go to your ’, // 2: a string { children: ['inbox'] }, // 3: <Link> with a string child ' to see your new messages' // 4: another string ]
Nos seus arquivos de tradução, você teria Olá, <1>{{name}}</1>! Vá para sua <3>caixa de entrada</3> para ver suas novas mensagens.
A ginástica mental para descobrir o índice certo pode ser confusa.
Conclusão
Os usuários são muito mais propensos a interagir com produtos em seu próprio idioma, portanto, oferecer suporte para mais idiomas e regiões pode trazer a você usuários que seus concorrentes não conseguem acessar. Se você internacionalizar seu produto antecipadamente, será mais capaz de adicionar suporte para outras localidades à medida que você aumenta a escala.
Você pode reduzir o tempo de desenvolvimento com o Strapi. Com seu plugin de internacionalização, você pode criar diferentes versões de conteúdo para cada idioma e país em um editor fácil de usar. Todo o seu conteúdo está disponível através de endpoints de API, permitindo que você conecte facilmente seu frontend. Esteja você desenvolvendo para web ou mobile, Strapi pode ajudá-lo em seu processo de localização.
Caso você só trabalhe com Flutter, ainda existe diversos packages de tradução, que facilita a vida do desenvolvedor. Sobre i18n