Maison >interface Web >js tutoriel >TRADUIRE votre projet React avec i n'a jamais été aussi simple
Aujourd'hui, je vais vous montrer que traduire un projet ENTIER dans React n'a jamais été aussi simple qu'aujourd'hui. Mais vous devez d’abord savoir pourquoi cela serait important.
Lorsque les gens commencent à programmer, il est courant que les textes de code et les messages soient en portugais (pt-BR). Traduire le projet dans d’autres langues n’est jamais une priorité et est considéré comme complexe ou inutile.
Cela dépend de votre réalité. Voici quelques raisons pour lesquelles vous devriez envisager ce processus :
L'entreprise en a besoin
Il se peut que l'entreprise dans laquelle vous travaillez ou un SaaS que vous possédez commence à opérer dans un autre pays et ait ce besoin. Un produit doté de cette fonctionnalité a une ÉNORME différence.
Candidature à un poste vacant à l'international
Si vous postulez à des postes vacants à l’international, disposer d’un portefeuille de projets déjà internationalisés peut vous offrir un atout marquant. Cela montre que vous êtes prêt à travailler sur un projet global et que vous n'êtes pas paresseux comme la plupart.
On ne peut jamais trop apprendre
L'internationalisation n'est pas seulement une caractéristique, mais aussi une expérience d'apprentissage importante. C'est une autre arme que vous incluez dans votre arsenal de compétences et d'outils.
La traduction de projets est déjà un vieux problème. Les gens ont fait cette sélection dans le HTML avec le drapeau du pays pour que les gens puissent le sélectionner et l'ont rempli avec si dans le code pour savoir quel texte serait affiché.
Cela a été très négligé. Les sites Web étaient créés dans une seule langue et les traductions étaient ajoutées au hasard. Si c'était dans le backend, l'affaire serait encore pire.
Avec la mondialisation d'Internet, la demande de logiciels multilingues s'est accrue, apportant des outils spécifiques pour i18n. Des solutions comme GNU Gettext ont émergé sur le backend, suivies par des bibliothèques comme i18next et réagissent-intl pour le frontend. C'est là qu'intervient le doute...
i18next : Celui-ci est apparu en 2011, c'était un package npm qui fonctionnait à la fois pour Node.js et SPA côté client. La communauté l'a adopté et a finalement réalisé la version React dans la libreact-i18next en 2015. Par conséquent, comme points positifs et négatifs nous avons :
react-intl : fait partie du projet FormatJS, suit les normes internationales de l'API JavaScript, garantissant la compatibilité avec les navigateurs modernes.
i18next mes amis ! Je recommande toujours de lire la documentation pour commencer, mais passons au guide de Doido !
npm install i18next i18next-chained-backend i18next-http-backend i18next-resources-to-backend react-i18next next-i18next
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import Backend from 'i18next-http-backend'; import LanguageDetector from 'i18next-browser-languagedetector'; i18n .use(Backend) .use(LanguageDetector) .use(initReactI18next) .init({ fallbackLng: 'en', interpolation: { escapeValue: false } }); export default i18n;
{ "welcome": "Welcome to our application!", "login": "Login" }
import React from 'react'; import { useTranslation } from 'react-i18next'; function App() { const { t } = useTranslation(); return ( <div> <h1>{t('welcome')}</h1> <button>{t('login')}</button> </div> ); } export default App;
import React from 'react'; import { useTranslation } from 'react-i18next'; function LanguageSwitcher() { const { i18n } = useTranslation(); const changeLanguage = (lng) => i18n.changeLanguage(lng); return ( <div> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('pt')}>Português</button> </div> ); } export default LanguageSwitcher;
Bien sûr que non, je vais maintenant vous montrer ce que j'ai fait dans le projet CrazyStack. J'ai d'abord fait une configuration différente dans Nextjs en prenant un JSON statique que j'ai défini dans le dossier public du projet lui-même ! Jetez un oeil :
import i18next from "i18next"; import ChainedBackend from "i18next-chained-backend"; import HttpBackend from "i18next-http-backend"; import resourcesToBackend from "i18next-resources-to-backend"; import { initReactI18next } from "react-i18next"; import { defaultTexts } from "./defaultTexts"; i18next .use(ChainedBackend) .use(initReactI18next) .init({ lng: "pt-br", fallbackLng: "pt-br", interpolation: { escapeValue: false, }, compatibilityJSON: "v3", react: { //wait: true,//usar no react native useSuspense: false, }, backend: { backends: [HttpBackend, resourcesToBackend(defaultTexts)], backendOptions: [ { loadPath: `${process.env.NEXT_PUBLIC_URL}/{{lng}}/{{ns}}.json`, }, ], }, });
Ensuite j'ai créé une API de contexte pour sauvegarder le langage et y accéder tout au long du projet. Commençons par les importations
import { useTranslation } from "react-i18next"; import { createContext, useState, useContext } from "react";
const I18NContext = createContext({} as any);
Un contexte est créé pour stocker et fournir des données (telles que la langue actuelle) via le DOM.
export const isBrowser = typeof window !== "undefined";
Essa linha verifica se o código está sendo executado no navegador (em vez de no servidor), essencial para manipular recursos específicos do cliente, como localStorage.
export const I18nProvider = ({ children }: any) => { const { i18n } = useTranslation() || {}; const [currentLanguage, setCurrentLanguage] = useState( formatLanguageFromi18N(i18n?.language) ); const changeLanguage = (language) => { setCurrentLanguage(language); i18n?.changeLanguage?.(formatLanguageFromSelect(language)); localStorage.setItem("language", formatLanguageFromSelect(language)); }; return ( <I18NContext.Provider value={{ changeLanguage, currentLanguage, setCurrentLanguage }}> {children} </I18NContext.Provider> ); };
Este componente é um provider que envolve a árvore de componentes React e fornece o estado atual do idioma e a função para alterá-lo.
export const useI18n = () => { if (!isBrowser) { return { currentLanguage: "pt-br", setCurrentLanguage: () => {}, changeLanguage: () => {}, }; } return useContext(I18NContext); };
Este hook facilita o acesso ao contexto de internacionalização em qualquer componente.
const countryToLanguage = { BR: "pt-br", US: "en", }; const languageToCountry = { "pt-br": "BR", en: "US", };
Esses objetos mapeiam códigos de países para códigos de idiomas e vice-versa, facilitando a formatação dos códigos de idioma entre diferentes convenções.
export const formatLanguageFromi18N = (language) => languageToCountry[language]; export const formatLanguageFromSelect = (language) => countryToLanguage[language];
Essas funções formatam os códigos de idioma conforme necessário. formatLanguageFromi18N converte o código de idioma para o código do país, enquanto formatLanguageFromSelect faz a conversão inversa.
"use client"; import { useTranslation } from "react-i18next"; import { createContext, useState, useContext } from "react"; const I18NContext = createContext({} as any); export const isBrowser = typeof window !== "undefined"; export const I18nProvider = ({ children }: any) => { const { i18n } = useTranslation() || {}; const [currentLanguage, setCurrentLanguage] = useState( formatLanguageFromi18N(i18n?.language) ); const changeLanguage = (language) => { setCurrentLanguage(language); i18n?.changeLanguage?.(formatLanguageFromSelect(language)); localStorage.setItem("language", formatLanguageFromSelect(language)); }; return ( <I18NContext.Provider value={{ changeLanguage, currentLanguage, setCurrentLanguage }}> {children} </I18NContext.Provider> ); }; export const useI18n = () => { if (!isBrowser) { return { currentLanguage: "pt-br", setCurrentLanguage: () => {}, changeLanguage: () => {}, }; } return useContext(I18NContext); }; const countryToLanguage = { BR: "pt-br", US: "en", }; const languageToCountry = { "pt-br": "BR", en: "US", }; export const formatLanguageFromi18N = (language) => languageToCountry[language]; export const formatLanguageFromSelect = (language) => countryToLanguage[language];
No código eu tenho um select de idioma utilizando um dropdown de países. Olha só:
"use client"; //@ts-nocheck import { Header, Flex, Logo, Profile, NotificationsNav, SearchBar } from "@/shared/ui"; import { useBreakpointValue, Icon, IconButton, useMediaQuery } from "@chakra-ui/react"; import { RiMenuLine } from "react-icons/ri"; import { useAuth, useSidebarDrawer } from "@/shared/libs"; import { useEffect, useState } from "react"; import { CountryDropdown } from "react-country-region-selector"; import { theme } from "@/application/theme"; import { formatLanguageFromi18N, useI18n } from "@/application/providers/i18nProvider"; import { useTranslation } from "react-i18next"; export const NavBar = ({ showLogo = true }) => { const { isAuthenticated } = useAuth() || {}; const { i18n } = useTranslation(); const { changeLanguage, setCurrentLanguage } = useI18n() || {}; const { onOpen = () => {}, onClose } = useSidebarDrawer() || {}; const isDesktopVersion = useBreakpointValue({ base: false, lg: true }); const [country, setCountry] = useState(formatLanguageFromi18N(i18n?.language)); useEffect(() => { return () => { onClose?.(); }; }, []); const Dropdown = CountryDropdown as any; useEffect(() => { const language = localStorage.getItem("language"); if (language) { setCountry(formatLanguageFromi18N(language)); setCurrentLanguage(language); i18n?.changeLanguage?.(language); } }, []); return ( <Header> <Flex alignItems={"center"} w={"100%"}> {isAuthenticated && !isDesktopVersion && ( <IconButton aria-label="Open sidebar" fontSize="24" icon={<Icon as={RiMenuLine} />} variant="unstyled" onClick={onOpen} mr="1" mt={2} /> )} <Logo marginBottom={0} /> {/* {isLargerThan560 && ( <SearchBar placeholder="Pesquise por nome..." name="search" width="auto" /> )} */} {isAuthenticated && ( <Flex align="center" ml="auto"> {/* <NotificationsNav /> */} <Dropdown value={country} onChange={(val) => { setCountry(val); changeLanguage(val); }} labelType="short" valueType="short" showDefaultOption defaultOptionLabel="Selecione o idioma" whitelist={["US", "BR"]} style={{ backgroundColor: theme.colors.secondary[400], padding: 10, width: 60, marginRight: 15, borderRadius: 8, }} /> <Profile showProfileData={isDesktopVersion} /> </Flex> )} </Flex> </Header> ); };
Importações e Setup Inicial:
Dropdown de Idiomas:
De componente em componente eu fui fazendo o mesmo procedimento. O código abaixo mostra como substituir o texto estático por uma tradução dinâmica baseada na chave de localização:
import { Divider } from "@chakra-ui/react"; import { IoExitOutline } from "react-icons/io5"; import { useRouter } from "next/navigation"; import { useTranslation } from "react-i18next"; // Importando o hook useTranslation type ProfileProps = { showProfileData?: boolean; }; export const Profile = ({ showProfileData }: ProfileProps) => { const { t } = useTranslation(["PAGES"]); // Obtendo a função t para tradução const { user, logout } = useAuth() || {}; const router = useRouter(); const { showUserMenu, setShowUserMenu } = useProfile(); return ( <Box> {/* Outras partes do componente */} <Flex> <IoExitOutline /> <Text fontSize="sm"> {t("PAGES:HOME_PAGE.logout", { defaultValue: "Sair" })} // Chave de tradução com valor padrão </Text> </Flex> </Box> ); };
Neste exemplo, o hook useTranslation é utilizado para carregar a chave de tradução PAGES:HOME_PAGE.logout. Se a chave não for encontrada, o texto padrão "Sair" será exibido.
A ideia pode ser aplicada em qualquer componente de texto estático. Basta usar a hook useTranslation.
Internacionalizar sua aplicação pode abrir portas para mercados globais, destacar seu portfólio e aprimorar suas habilidades. Escolher entre i18next e react-intl depende das necessidades específicas do seu projeto, mas ambos são excelentes opções para quem deseja começar.
Em 2022 eu criei o bootcamp CrazyStack. Nele, eu mostro 2 aplicações completas de um sistema de agendamentos online de serviços aplicando conceitos avançados como Design Patterns, Clean Architecture, Feature Sliced Design, SOLID, DDD, além de Testes unitários, de integração e E2E.
Dans la première application, vous apprendrez à créer une API REST dans l'écosystème Node.js. Des cas d'utilisation seront créés impliquant des règles commerciales complexes telles que la liste des heures disponibles, la génération de commandes à partir de rendez-vous réservés, les systèmes de fidélisation, les commissions, les paiements, les avis clients et bien plus encore. Tout est fait en TypeScript et en utilisant la base de données non relationnelle MongoDB.
Dans la deuxième application, vous apprendrez à créer un panneau d'administration dans l'écosystème React.js pour afficher des graphiques et manipuler des enregistrements. Tout est fait avec TypeScript et en utilisant le framework Next.js. De plus, la bibliothèque de composants visuels Chakra UI sera utilisée, appliquant le concept Atomic Design aux composants créés. Pour en savoir plus, visitez crazystack.com.br.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!