今日は、プロジェクト全体を React に変換することが、今ほど簡単になったことはないということを説明します。しかし、まずこれがなぜ重要なのかを知る必要があります。
プログラミングを始めるとき、コード テキストとメッセージがポルトガル語 (pt-BR) であるのが一般的です。プロジェクトを他の言語に翻訳することは決して優先事項ではなく、複雑であるか不必要であると考えられています。
それはあなたの現実次第です。このプロセスを検討する必要がある理由は次のとおりです:
会社はそれを必要としています
あなたが働いている会社、またはあなたが所有しているいくつかの SaaS が別の国で事業を開始し、このニーズを抱えている可能性があります。この機能を備えた製品には大きな違いがあります。
海外求人への応募
国際的な求人に応募する場合、すでに国際化されたプロジェクトを含むポートフォリオを持っていると、印象的なハイライトを得ることができます。これは、あなたが世界的なプロジェクトに取り組む準備ができており、ほとんどの人のように怠け者ではないことを示しています。
学びすぎることはありません
国際化は単なる機能ではなく、重要な学習体験でもあります。これは、スキルやツールの武器庫に含めるもう 1 つの武器です。
プロジェクトの翻訳はすでに古い問題です。人々は、HTML 内で国旗を選択できるようにその選択を作成し、どのテキストが表示されるかを知るためにコード内に if を入力しました。
とても無視されていました。ウェブサイトは単一言語で作成され、翻訳は無計画に追加されました。それがバックエンドにあった場合、取引はさらに悪化したでしょう。
インターネットのグローバル化に伴い、多言語ソフトウェアの需要が高まり、i18n に特化したツールが提供されています。 GNU Gettext のようなソリューションがバックエンドで登場し、その後、フロントエンド用の i18next や reverse-intl などのライブラリが登場しました。ここで疑問が生じます...
i18next: これは 2011 年に登場した、クライアント側の Node.js と SPA の両方で動作する npm パッケージでした。コミュニティはそれを採用し、最終的に 2015 年に React バージョンを React-i18next ライブラリに作成しました。したがって、ポジティブな点とネガティブな点としては次のとおりです。
react-intl: FormatJS プロジェクトの一部であり、国際 JavaScript API 標準に従い、最新のブラウザーとの互換性を確保します。
i18次は友達!始めるにはドキュメントを読むことを常にお勧めしますが、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;
もちろんそうではありません。次に、CrazyStack プロジェクトで私が行ったことを紹介します。まず、プロジェクト自体のパブリック フォルダーで定義した静的 JSON を取得して、Nextjs で別の構成を作成しました。見てみましょう:
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`, }, ], }, });
次に、言語を保存し、プロジェクト全体でアクセスするためのコンテキスト API を作成しました。輸入から始める
import { useTranslation } from "react-i18next"; import { createContext, useState, useContext } from "react";
const I18NContext = createContext({} as any);
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.
最初のアプリケーションでは、Node.js エコシステムで REST API を構築する方法を学びます。利用可能な時間のリスト、予約された予約からの注文の生成、ロイヤルティ システム、手数料、支払い、顧客レビューなどの複雑なビジネス ルールを含むユース ケースが作成されます。すべては TypeScript で行われ、非リレーショナル データベース MongoDB を使用します。
2 番目のアプリケーションでは、React.js エコシステムで管理パネルを構築してグラフを表示し、レコードを操作する方法を学びます。すべて TypeScript と Next.js フレームワークを使用して行われます。さらに、Chakra UI ビジュアル コンポーネント ライブラリが使用され、Atomic Design の概念が作成されたコンポーネントに適用されます。詳細については、crazystack.com.br をご覧ください。
以上がi を使用した React プロジェクトの翻訳がかつてないほど簡単になりましたの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。