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

前端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。   #头条创作挑战赛#


想吃啥吃啥老詹小注想吃啥吃啥!这是德民兄的观点。有什么科学依据吗?他没有说。我来补充一下,我认为,人的身体,是我们这个星球上最最精密的仪器。它可以自发调节身体各种需求与供给。身体需要什么,它44岁章子怡同框42岁张柏芝,2岁之差如隔世纪,一个阿姨一个姐姐有些女人虽然仅仅只有几岁之差,但是看上去气质却截然不同,尤其是对于中年女性来说,一岁之差也会拉开气质上的差距。女人的气质其实不仅仅是看你的长相和身材,最重要的还是你的身姿体态,以及美白新思路,弯道超车快人一步!达妹最近发现,跟很多姐妹聊天,还是一谈美白就说成分,今天想给大家输入一些新思路,科普一下美白金字塔!1防晒美白金字塔的塔尖,是防晒。我认为,所有不谈防晒的美白都是耍流氓。防晒不仅是看了张兰向太的打扮,我悟了不烫大妈卷不披金挂银,优雅贵气穿搭显贵气,悦己又悦人。对于上了年纪的女人来说,在穿衣打扮上切记不能太随意邋遢,要学会利用造型来彰显贵气感,别人看着赏心悦目,自己也开心。影响造型贵气感的因素,不光取决于服装,还包杨紫琼时尚大片未来感十足穿透视装秀美腿显女王范2月17日,杨紫琼多元宇宙杂志大片发布,而本次杂志掌镜的是沉寂了一年多的中国时尚摄影教母陈漫。封面上,杨紫琼身穿金色立体刺绣大衣,手持银色折扇,仿佛女王的战袍,霸气十足。从照片可以痤疮有哪三大并发症?每种症状都令人难受,有的或会影响你一生梅芳,十六岁,她不像其他少女一样皮肤光滑,而是脸上满是痤疮,这也让她深深地自卑起来。她不敢让别人看到自己的脸,变得沉默寡言,总是低着头,不愿意和别人说话。梅芳的痤疮让她变得更加孤僻如何应对季节性皮肤瘙痒症,这里有干货季节性皮肤瘙痒症多发生在秋冬季节,发病人群以50岁以上男性为主,瘙痒可遍及全身,但以四肢为主尤其是小腿前方。其特点是皮肤没有明显的破损,皮疹,抓挠时有较多皮屑,留下抓痕。皮肤瘙痒发看完杭州女生街拍后才发现,今春短外套黑丝火了,时髦洋气提到时尚穿搭,大家都会想到魔都上海女生的穿衣打扮,实际上,杭州也是当之无愧的时尚之都,杭州女生的街拍造型丝毫不亚于上海,加上当下女生们穿衣都追求多元化发展,不再是以往一板一眼的风格4大疑团揭秘真相!吕亚童房屋强拆继续发酵,发文10问执法公信力最近关于女足队员吕亚童发文,政府强拆自家房屋,并未获得赔偿事件继续发酵。政府相关执法部门认为吕亚童房屋属于违建,不应该给予赔偿。双方各执一词谁是谁非,一下难以定论。但最近吕亚童发文陈戌源落马影响上海帮!孙雯主动让贤,朱广沪成耀东危险了?陈戌源落马,留给了中国足球一堆问号。而最大的问号显然是谁来接班陈戌源?中国足球到底需要什么样足协主席?关于下一任足协主席的人选,早在陈戌源还在位时,网络上就有很多力挺孙雯的声音此前围甲总决赛申真谞爆冷落败,江苏队逼平五冠王杭州队江苏队黄云嵩爆冷战胜韩国围棋第一人申真谞。新京报记者孙海光摄新京报讯(首席记者孙海光)2月17日,2022华为手机杯中国围棋甲级联赛在成都结束决赛首回合较量,江苏神兽腓腓队黄云嵩爆
闪耀!保利尼奥连场破门奥古斯托建功,助科林蒂安21取胜直播吧2月11日讯在巴西圣保罗州锦标赛中,保利尼奥和奥古斯托破门助科林蒂安取胜,泰山旧将格德斯则首发出战。科林蒂安周四晚间对阵米拉索尔,奥古斯托第19分钟帮助科林蒂安取得领先,这是100句神仙级官宣文案1hr浪漫文艺版1你是我的人间理想。2星河依然滚烫,我找到了我的太阳。3也许世界上也有五千朵和你一模一样的花,但4只有你是我独一无二的玫瑰。5柠檬从此变甜了。6成功加入柠檬供应商行今日文案丨可以置顶很久的短句文案1。我的心也会像海浪一样为你跳动无数次。2。月色暗淡还有星辰,山河失色还有我。3。冷漠的语气让我和你说话没了兴趣4。十几年前的暗恋多么不切实际可张万森确确实实默默喜欢了林北星十几年13日晨,一起去看最亮启明星,约吗?继2021年12月4日以长庚姿态现身的金星迎来全年最亮之后,2022年2月13日以启明姿态现身的金星将再次迎来全年最亮,届时如果天气晴好,有兴趣的公众可早起面向东南方天空观赏,看看看,这朵绽放了一亿年的花光明日报记者刘艳杰光明日报通讯员刘奕辰李鲲鹏近日,青岛科技大学王硕教授团队在国际知名学术期刊自然植物发表封面论文一亿年前琥珀中发现起源于南非的适火性鼠李科植物。该研究在国际上首次发韩国人犯规太无耻!裁判遭保安教练围殴,韩国体育精神有多脏在让人失望这件事儿上,印度人从来没让我们失望过,但是在不要脸这件事儿上,韩国人不仅做到了,甚至还能屡次刷新我们的下限,最直观的就体现在韩国人的体育精神方面。北京时间的2月7日,北京6分51秒05!中国又一夺金点诞生!接力摔倒判进决赛,王濛神预言北京时间2月11日,北京冬奥会短道速滑比赛继续展开争夺。晚上20点,短道速滑男子5000米接力半决赛打响,中国队在第一组出战,同组对手有加拿大队意大利队日本队。经过一番激烈角逐,中哈登离队但篮网问题还在,欧文进进出出,西蒙斯也是火药桶在截止日的最后关口,篮网队还是做出了关键的决定。将哈登和米尔萨普打包送到费城,换来西蒙斯小库里庄神以及两个首轮签。在多家媒体看来,篮网是这笔交易当中的大赢家,他们不仅换回了一位全明冰墩墩都跳起来!华东师大编创16套冬奥体操,要火梦之队华东师大全明星健美操啦啦操队编制16套健身操营造具有感染力的竞技氛围和具有奥运会主办国特色的赛场文化氛围看台加油手势舞受国家体育总局委托,华东师范大学体育与健康学院教授健美操给运动员的奖金需要缴个税吗?近日,中国女足夺得了女足亚洲杯冠军,2022年北京冬奥会也在如火如荼进行,短道速滑队获得了首金,中国的运动健儿们在赛场上奋勇拼搏,为国争光的同时,还少不了摘金夺银的奖励。一方面,国最感人的散文回不去的故乡回不去的故乡张巧(一)2019。12。18按照农历算,今天是父亲的一周年忌日,我们齐聚在上秦的家中,为父亲过周年。我悄悄离开喧闹的人群,迎着冽冽的寒风,独自走向这冬日空旷的田野。我