
今天我将向您展示,将整个项目翻译成 react 从未像现在这样容易。但首先您需要知道为什么这很重要。
当人们开始编程时,代码文本和消息通常使用葡萄牙语(pt-br)。将项目翻译成其他语言从来都不是优先事项,并且被认为是复杂或不必要的。
这取决于你的实际情况。以下是您应该考虑此过程的一些原因:
公司需要
可能是您工作的公司或您拥有的某些 saas 开始在另一个国家/地区运营并且有此需求。具有此功能的产品有巨大的差异。
申请国际职位空缺
如果您正在申请国际职位空缺,拥有包含国际化项目的作品集可以给您带来引人注目的亮点。这表明您已准备好从事全球项目,并且不像大多数人一样懒惰。
你永远不会学太多
国际化不仅是一种特征,也是一种重要的学习经历。这是您的技能和工具库中的另一种武器。
项目翻译已经是个老问题了。人们在 html 中选择了该国家的国旗,供人们选择,并在代码中用 if 填充以了解将显示哪些文本。
这是非常被忽视的。网站是用单一语言制作的,翻译是随意添加的。如果是在后端,交易会更糟糕。
随着互联网的全球化,对多语言软件的需求不断增长,带来了针对国际化的特定工具。像 gnu gettext 这样的解决方案出现在后端,随后出现了像 i18next 和 react-intl 这样的前端库。然后疑问就来了...
i18next:这个出现于 2011 年,它是一个 npm 包,适用于客户端的 node.js 和 spa。社区采纳了它,并最终于2015年在react-i18next lib中制作了react版本。因此,作为积极和消极的点,我们有:
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 项目中做了什么。首先,我在 nextjs 中做了一个不同的配置,采用了我在项目本身的公共文件夹中定义的静态 json!看看:
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";
此行检查代码是否在浏览器中运行(而不是在服务器上),这对于处理 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>
);
};
这个组件是一个provider,它包装了react组件树并提供了语言的当前状态以及更改它的函数。
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];
这些函数根据需要格式化语言环境。 formatlanguagefromi18n 将语言代码转换为国家/地区代码,而 formatlanguagefromselect 则进行反向转换。
"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];
在代码中,我使用国家/地区下拉菜单选择语言。看看:
"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>
);
};
导入和初始设置:
语言下拉菜单:
从一个组件到另一个组件,我都遵循相同的过程。下面的代码展示了如何根据本地化密钥用动态翻译替换静态文本:
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>
);
};
在此示例中,usetranslation 挂钩用于加载 pages:home_page.logout 翻译键。如果未找到该密钥,将显示默认文本“退出”。
这个想法可以应用于任何静态文本组件。只需使用 usetranslation 钩子即可。
国际化您的应用程序可以打开全球市场的大门,突出您的投资组合并提高您的技能。在 i18next 和 react-intl 之间进行选择取决于您项目的具体需求,但对于那些想要入门的人来说,两者都是很好的选择。
2022 年,我创建了crazystack 训练营。在其中,我展示了在线服务调度系统的 2 个完整应用程序,应用了设计模式、简洁架构、功能切片设计、solid、ddd 以及单元、集成和 e2e 测试等先进概念。
在第一个应用程序中,您将学习如何在 node.js 生态系统中构建 rest api。将创建涉及复杂业务规则的用例,例如列出可用时间、根据预订生成订单、忠诚度系统、佣金、付款、客户评论等等。一切都在 typescript 中完成并使用非关系数据库 mongodb。
在第二个应用程序中,您将学习如何在 react.js 生态系统中构建管理面板来查看图表和操作记录。一切都是通过 typescript 和 next.js 框架完成的。此外,还将使用chakra ui可视化组件库,将原子设计概念应用于创建的组件。要了解更多信息,请访问crazystack.com.br。
以上就是使用 i 翻译你的 React 项目从未如此简单的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号