范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

前端i18n最佳实践在React中使用i18next

  本合集文章,授权转载,侵权必究。
  来源 : 代码与野兽
  本文将会介绍 i18n 的业界最佳实践。
  聊聊什么是 i18n?JavaScript 中的 i18n 基本概念
  目前业界最流行的 i18n 方案都需要处理两个东西: 资源文件 路由 资源文件
  i18n 这个问题在前后端未分离的时代就一直存在。
  实现 i18n,可以分为后端 runtime 的策略和前端 runtime 的策略。
  先讲一下后端 runtime 的策略。
  比如在 JSP 和 PHP 模板引擎中就有大量基于这种策略实现的 i18n。
  它会把网页中要显示的内容提前翻译成多种语言。
  当用户请求网页时,由用户自己选择语言,或者在第一次用户没选择语言时使用服务端接收到的 accept-language 请求头字段来确定用户的语言。
  之后去加载写死的模板字符串资源文件,去替换文本内容。
  拿代码举个大概的例子。
  这是原来没有做国际化的代码。 这是一段简单的文本
  做完国际化后。{t("simpleContent")}
  其实就是提供了一个 t 函数(就是 translation 的缩写),它可以翻译文本。
  资源文件可以是 JSON,或者是其他格式的文件,内容大概如下:{   "en": {     "simpleContent": "Just simple content"   },   "zh": {     "simpleContent": "这是一段简单的文本"   } }
  前端 runtime 的策略原理和上面的类似,就是提前定义一堆 JavaScript 对象,然后去动态获取它的值而已。
  这么看来似乎前端 runtime 策略似乎更加简单,但在实际上几乎没有什么人会用这种方案,因为它有一个致命缺点,就是不支持 SEO。
  国际化的目的本来就是服务更多的用户群体,考虑做国际化的站点,基本上也会考虑做 SEO。路由
  早期的网站很多都没有考虑路由的问题,所有国家的用户都访问同一个网站。但是当中国的用户分享了他老婆网址,他老婆精通中英双语,但是她老婆的浏览器默认是英语,对方想直接看到中文的内容,还需要手动切换语言,很麻烦。而且有些语言的书写和排列都和英语、汉语这类语言不一样,需要单独调整样式。
  基于这些需求,现代的网站在做国际化时都喜欢区分路由,比如 web.dev 的网址,中文访问是这个地址:web.dev/i18n/zh/web…,英文访问是这个地址:web.dev/i18n/en/web…。
  甚至还可以转发网址,比如中国用户访问 xxx.cn,美国用户访问 xxx.com。最流行的 i18n 库
  从 npm 周下载量上看,i18next 无疑是最流行的 i18n 库。
  i18next 之所以如此受欢迎,是因为 i18next 不仅仅是针对 React 或者某个框架而设计的,甚至都不是针对 Web 这个平台而设计的。它可以用在 Node.js、Deno、.NET、php、ruby、IOS、Android 等一系列平台上。
  而且 i18next 也足够老,从 2011 年末就开源了,比 React、Vue 这些前端框架都要老,经过了很长时间的考验,基本上没有什么 i18n 领域的问题是它解决不了的。在 React 中使用 i18next
  为了更好的适配 React 这个框架,社区又基于 i18n 开发了 react-i18next 这个库。
  接下来我会完成一个简单的案例,带大家快速学习 react-i18next。基本用法
  首先创建项目。npx create-react-app react-i18n
  然后安装 i18-next 的依赖项。npm i i18next react-i18next i18next-browser-languagedetector 复制代码i18next 提供了翻译的基本能力。react-i18next 是 i18next 的一个插件,用来降低 react 的使用成本。i18next-browser-languagedetector 是用来检测浏览器语言的插件。
  创建 i18n.js,具体的注释都在代码中。import i18n from "i18next"; import { initReactI18next } from "react-i18next"; import LanguageDetector from "i18next-browser-languagedetector";  i18n   // 检测用户当前使用的语言   // 文档: https://github.com/i18next/i18next-browser-languageDetector   .use(LanguageDetector)   // 注入 react-i18next 实例   .use(initReactI18next)   // 初始化 i18next   // 配置参数的文档: https://www.i18next.com/overview/configuration-options   .init({     debug: true,     fallbackLng: "en",     interpolation: {       escapeValue: false,     },     resources: {       en: {         translation: {           // 这里是我们的翻译文本         }       }     }   });  export default i18n;
  在 index.js 中导入 i18n.js。import "./i18n.js"
  重新编写 App.js 中的内容。import { useTranslation, Trans } from "react-i18next";  function App() {   const { t } = useTranslation();   return (            

{t("welcome")} 作者是: {Date.now()}

); } export default App;   其中使用到了 useTranslation 这个 Hooks,以及 Trans 这个组件。   useTranslation 返回的对象包含一个 t 方法,这个方法可以翻译文本。   Trans 可以翻译一个组件树。   打开浏览器,这时显示下面的内容:   我们去 i18n.js 中添加翻译。import i18n from "i18next"; import { initReactI18next } from "react-i18next"; import LanguageDetector from "i18next-browser-languagedetector"; i18n // 检测用户当前使用的语言 // 文档: https://github.com/i18next/i18next-browser-languageDetector .use(LanguageDetector) // 注入 react-i18next 实例 .use(initReactI18next) // 初始化 i18next // 配置参数的文档: https://www.i18next.com/overview/configuration-options .init({ debug: true, fallbackLng: "en", interpolation: { escapeValue: false, }, resources: { en: { translation: { // 这里是我们的翻译文本 welcome: "Welcome to my website", author: `Author is:<1>code and beast`, } }, zh: { translation: { welcome: "欢迎来到我的网站", author: `作者是:<1>代码与野兽`, } } } }); export default i18n;   现在显示正常了。   接下来我们再来测试浏览器是英文的情况。   我用的是 Chrome 浏览器,其他浏览器操作步骤类似。   在浏览器设置中搜索 languages。   点击 add languages,选择 English。   然后需要 Move to the top,把 English 设置为首选语言。   重启浏览器。   这时就被翻译成英语了。   语言翻译器   接下来我们实现一个语言切换的功能。import { useTranslation, Trans } from "react-i18next"; const lngs = { en: { nativeName: "English" }, zh: { nativeName: "中文" } }; function App() { const { t, i18n } = useTranslation(); return (

{t("welcome")} 作者是: {Date.now()}

); } export default App;   核心代码是 useTranslation 返回的 i18n.changeLanguage 方法,这个方法可以修改用户的当前语言。   不过 i18next-browser-languagedetector 会自动尝试检测浏览器的默认语言,我们可以把用户上次手动选择的语言存储到 localStorage 中,下次访问页面时使用上次存储的语言作为首选语言。插值表达式   这时你可能会问了,当我们碰到要翻译的内容中存在变量时该怎么办?   i18next 提供了插值的用法。   我们在 t 函数中传递第二个参数,它是一个对象。   比如我们要显示当前时间。   首先安装 dayjs。npm i day.js   添加一个元素。

{t("currentTime", { time: dayjs().format("MM/DD/YYYY") })}   然后在 i18n.js 中添加翻译的文本。{ resources: { en: { translation: { // 这里是我们的翻译文本 welcome: "Welcome to my website", author: `Author is:<1>code and beast`, currentTime: "Current time is {{time}}", } }, zh: { translation: { welcome: "欢迎来到我的网站", author: `作者是:<1>代码与野兽`, currentTime: "当前时间是 {{time}}", } } } }   插值表达式的语法是使用两个大花括号包裹属性名。格式化   如果你想对插值进行格式化,比如中文的日期显示 2022-09-05,英文日期显示05/09/22。该怎么做呢?   i18next 提供了格式化的能力。   首先差值表达式支持第二个值,它是格式化器的名字。{ resources: { en: { translation: { // 这里是我们的翻译文本 welcome: "Welcome to my website", author: `Author is:<1>code and beast`, currentTime: "Current time is {{time, DD/MM/YY}}", } }, zh: { translation: { welcome: "欢迎来到我的网站", author: `作者是:<1>代码与野兽`, currentTime: "当前时间是 {{time, YYYY-MM-DD}}", } } } }   然后添加两个格式化器。i18n.services.formatter.add("DD/MM/YY", (value, lng, options) => { return dayjs(value).format("DD/MM/YY") }); i18n.services.formatter.add("YYYY-MM-DD", (value, lng, options) => { return dayjs(value).format("YYYY-MM-DD") });   这样就实现了插值文本的格式化。   除了上面介绍的用法外,i18next 还有更多的功能,比如语境、复数、命名空间等。这里就不多做介绍了,详细的内容可以参考 i18next 的文档。将翻译文件与代码进行拆分   通常来说,翻译的工作不是程序员干的,而是有专业的业务团队去负责翻译,因为他们对业务术语等更加了解。   为了方便维护,我们可以选择使用 json 文件来作为保存翻译文本的资源文件。   首先需要安装一个库:i18next-http-backend。npm install i18next-http-backend 复制代码   然后修改 i18n.js 的内容,将这个插件用上,并且删除掉原来的 resources 字段。import i18n from "i18next"; import { initReactI18next } from "react-i18next"; import LanguageDetector from "i18next-browser-languagedetector"; import dayjs from "dayjs" import Backend from "i18next-http-backend"; i18n .use(Backend) // 检测用户当前使用的语言 // 文档: https://github.com/i18next/i18next-browser-languageDetector .use(LanguageDetector) // 注入 react-i18next 实例 .use(initReactI18next) // 初始化 i18next // 配置参数的文档: https://www.i18next.com/overview/configuration-options .init({ debug: true, fallbackLng: "en", interpolation: { escapeValue: false, }, }); // new usage i18n.services.formatter.add("DD/MM/YY", (value, lng, options) => { return dayjs(value).format("DD/MM/YY") }); i18n.services.formatter.add("YYYY-MM-DD", (value, lng, options) => { return dayjs(value).format("YYYY-MM-DD") }); export default i18n; 复制代码   然后在 public 下面创建 locales 目录,在这个目录下创建和语言缩写对应的文件夹,其中放置 translation.json 文件。这个命名是约定好的,backend 插件会去按照这个路径请求资源文件。   翻译的内容和 resources 的内容一模一样。   比如 zh/translation.json 的内容如下:{ "welcome": "欢迎来到我的网站", "author": "作者是:<1>代码与野兽", "currentTime": "当前时间是 {{time, YYYY-MM-DD}}" } 复制代码   但是这样会让资源文件以异步的方式进行请求,如果网络存在波动,那么有可能请求资源文件失败。   所以我们还要使用 Suspense 组件处理加载出错。import { Suspense } from "react"; function App() { // ... } export default function WrappedApp() { return ( ); } 复制代码locize 平台   i18next 有自己的翻译平台 locize.app/。   这个平台可以帮助我们整合翻译服务、追踪翻译的更改、版本、机器翻译等一系列功能,它会让我们管理翻译资源文件就像管理代码一样。   当我们的全球化业务非常庞大时,采用这个平台来处理 i18n 问题会更加轻松。   文中介绍的代码部分均为客户端 runtime 翻译,在更多的实际情况下我们会选择服务端 runtime 翻译,这时可能会使用 nextjs 这种 SSR 框架来处理 i18n。   #头条创作挑战赛#


老人家常说,晨不吐口水,午不泄精水,晚不流汗水,是什么意思?中华文明上下五千年,老祖宗总结出众多经验之谈,有一定的科学道理,照着做对身体健康有益处。家中老人常常说晨不吐口水,午不泄精水,晚不流汗水,这到底是什么意思,是否有科学道理呢。这句话老话说冬不藏精,春必病温,怎么藏?男性多看看黄帝内经中提到冬三月,此谓闭藏此冬气之应,养藏之道也逆之则伤肾,春为痿厥,奉生者少。男性比女性强壮,身体素质更强,但纵观世界各国,古今中外,女性的平均寿命总是要长于男性,男女的平均俗话说老泻残精,人穷寿尽,是什么意思?想安度晚年,要3不做我国有5000年的历史,各方面的文化也博大精深,其中则包括俗语,虽然道理浅显,而且朗朗上口,但是对人类的影响却比较大,有时甚至能够从其中悟出一些养生道理,比如老泻残精,人穷寿尽,则芝麻搭配这些食材,好比吃补品肾气足精神好睡得香气色红润俗话说十人九虚。很多人过了30岁,都会有这样的感觉容易掉发腰膝酸软记忆力大不如从前晚上睡不好白天又困乏无力这可能是你肾气亏虚了!肾为先天之本肾藏精,其华在发,掉发白发睡眠和记忆力变乒坛新消息!孙颖莎解锁新身份,樊振东队友被爆丑闻秦志戬遇难题12月7日,在经历了短暂的休整后,乒超联赛比赛继续进行。这不,乒坛传来两个新消息,一个是国乒世界冠军孙颖莎解锁了新身份,据悉石家庄法治宣传教育领导小组已经发布消息,聘请孙颖莎担任石巴克利亚历山大是今年联盟最好的得分后卫他现在所做的事很酷直播吧12月7日讯今日,NBA评论员巴克利在节目中谈到了雷霆后卫亚历山大。巴克利认为在我看来,亚历山大是今年联盟最好的得分后卫。他现在所做的事实在是太棒了,雷霆正打出很有竞争力的篮NBA西部排名榜鹈鹕垂涎榜首,太阳危矣独行侠升2名,湖人倒第312月7日,东西部6支球队进行了3场常规赛湖人102116骑士,活塞11696热火,独行侠116115掘金。目前西部排名榜竞争异常激烈鹈鹕坐二望一,太阳榜首位置岌岌可危,独行侠杀回冬养肾,身上暖建议中老年人做好这2点,身体强健,舒服过冬按照中医五行理论,冬季对应的是肾脏。现在正值冬季,正是开始补肾养肾的最佳季节。肾气不足畏寒肢冷,精神萎靡。肾气充足,身体强健,不惧寒冷,腿脚有劲。补肾要得当中医认为,个人体质强弱与性能车成95后新宠,悟空租车6000车型助力冬季自驾出行现如今,自驾旅游越来越受到人们的追捧,在旅游市场中所占的比重越来越大,逐渐成为旅游的主流方式。而随着多省放开疫情防控,今年冬季滑雪季已拉开大幕,作为后奥运崇礼首个雪季,不少人选择自冬季要常吃它,比猪肉牛肉要便宜,营养好消化,每次上桌就光盘头条创作挑战赛进入冬天以来,寒风刺骨,冷得让人浑身发抖,马上要迎来大雪节气,大雪节气是冬季第三个节气,南方和北方都开始降温,一些城市开始降雪了,气温逐渐变冷了,脖子和脸部都被冻红了上古四大辅臣之前疑潘朝晖文在古代,年幼的帝王继位时往往会指定辅政大臣。据说,夏朝时就已经设有四大辅臣,分别称为前疑后丞左辅右弼,但真正被后世公认的当数西周初期周成王的四大辅臣(又称周初四圣)一一大前
11月通胀以今年最慢的速度上升,超出预期经济学家说,随着通货膨胀的发生,未来的下一个危险是经济衰退经济学家表示,11月消费者价格指数(CPI)的通胀数据好于预期,这意味着美联储可能会在下次会议上放慢加息速度。(iStoc致敬改革开放致敬民营企业家刘永好刘永好是在改革大潮中成长起来的一代企业家,他跟随着改革的号角前进,与创办的新希望集团一起稳步成长,作为民营企业家的优秀代表,在2018年被党中央国务院评为改革开放先锋人物,颁授改革青海春天难春天,张雪峰打造的听花酒销量惨淡12月12日,据上交所披露公告,对青海春天药用资源科技股份有限公司(以下简称青海春天)及有关责任人予以监管警示,原因是青海春天未对推广服务费进行合理的会计处理,其收入确认存在会计差融创功亏一篑2022年12月9日,融创中国(01918。HK)披露2021年业绩(非标准)公告。这份迟到大半年的财务报告并非年度报告,而且还是非标的。2022年5月12日,融创公告称因流动性压今天,辣条IPO来了卫龙正式敲钟第一个辣条IPO正式诞生。投资界天天IPO获悉,今日(12月15日),中国辣味休闲食品企业卫龙美味全球控股有限公司(简称卫龙)正式登陆港交所IPO舞台。此次IPO,卫龙净筹资8。9压缩机零部件龙头,星帅尔基本盘稳健,新能源拓展第二增长曲线(报告出品方分析师开源证券吕明周嘉乐陆帅坤)1星帅尔压缩机零部件龙头基本盘稳健,新能源业务放量拓展第二增长曲线1。1围绕压缩机零部件扩充产品矩阵,光伏组件及储能业务迎来放量杭州星帅乡游黔中贵定县清定桥村依山傍水,金海雪山上的美丽驿站来源贵州省文化和旅游厅文旅动态虽然天气逐渐转冷但是大家运动的热情却愈发高涨何不趁着如此美景开启一场骑行之旅黔南州贵定县盘江镇清定桥村位于贵州省贵定县盘江镇,是镇政府驻地,贵新高等级今年前10月普吉接待超232万名外游,旅游创收全泰第一!12月15日,泰国总理办公室副发言人缇帕婻透露,自泰国政府提出普吉沙盒计划并逐步推动全国开放后,旅游业发展在疫情期间取得了良好成绩,截至12月10日,赴泰外游已突破1000万名。据喜讯!临夏市折桥湾景区被评定为国家AAA级旅游景区12月15日,临夏州文化广电和旅游局发布关于批准11家景区为国家A级旅游景区的公告,其中临夏市折桥湾景区被评定为国家3A级旅游景区。折桥湾景区位于临夏市东郊,南临大夏河,北依北塬山比西巴格乡我和亲戚游家乡民族团结情更浓民族团结是我国各族人民的生命线,中华民族共同体意识是民族团结之本。为进一步密切干群关系,增进民族团结,促进各民族交往交流交融,不断铸牢各族干部群众中华民族共同体意识。比西巴格乡各村嘉庆年间,县尉夫人为赚钱,脱光衣服代妓受杖,满足县令变态嗜好为了避免官员勾结地方,清朝规定,仕宦不得在五百里内。所谓千里求官只为财,不过若运气不好,也只能落得个客死异乡。嘉庆年间,有个浙江举子远赴云南担任县尉,结果莅任未满一年就撒手人寰了。