news 2026/9/21 2:31:28

TOAST UI Editor 国际化(i18n)完全指南:语言包机制、代码注册与自定义语言扩展

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TOAST UI Editor 国际化(i18n)完全指南:语言包机制、代码注册与自定义语言扩展

TOAST UI Editor 国际化(i18n)完全指南:语言包机制、代码注册与自定义语言扩展

【免费下载链接】tui.editor🍞📝 Markdown WYSIWYG Editor. GFM Standard + Chart & UML Extensible.项目地址: https://gitcode.com/gh_mirrors/tu/tui.editor

TOAST UI Editor 内置了一套完整的国际化(i18n)机制,允许开发者将编辑器工具栏、弹窗、提示等所有 UI 文案切换为多种语言,并可通过setLanguage静态方法覆盖默认文案甚至注册全新的语言包。本文以 docs/en/i18n.md 为骨架,结合 apps/editor/src/i18n/i18n.ts 等源码实现,完整讲解语言文件目录结构、20 余种内置语言代码、ESM/CommonJS/CDN 三种导入方式、三种典型使用场景以及新增语言文件的贡献流程,读完即可在项目中落地多语言编辑器。

一、i18n 机制概览:语言代码如何生效

TOAST UI Editor 的 i18n 采用「语言文件注册 + 实例选项指定」两步走的设计:

  1. 导入语言文件:每个语言文件在加载时会调用Editor.setLanguage(code, data)把一份完整的 UI 文案表注册到全局的I18n单例中;
  2. 指定实例语言:创建EditorViewer实例时,通过language选项传入已注册的语言代码,编辑器即按该语言渲染所有 UI 文案。

从源码看,这一机制由 apps/editor/src/i18n/i18n.ts 中的I18n类实现:

  • 默认语言代码为DEFAULT_CODE = 'en-US'
  • 构造函数将当前代码初始化为en-US,并初始化一个用于存放各语言文案表的Map
  • setCode(code)切换当前语言(未传参则回退到en-US);
  • setLanguage(codes, data)支持同时为一个或多个代码string | string[])注册文案表,且对已存在的语言执行浅合并(extend),这正是「局部覆盖」能力的底层来源;
  • get(key, code)按当前代码取文案,若该代码尚未注册则回退到en-US,若连默认文案都没有对应 key 则抛出There is no text key "..."错误。

实例创建时,apps/editor/src/editorCore.ts 会执行this.i18n.setCode(this.options.language)把实例选项写入 I18n 单例;而工具栏、切换开关、弹窗等 UI 组件则通过i18n.get('Markdown')i18n.get('Headings')等调用读取对应语言的文案(参见 apps/editor/src/ui/toolbarItemFactory.ts 与 apps/editor/src/ui/components/switch.ts)。

注意:I18n是全局单例(export default new I18n()),因此语言注册与当前代码切换是跨实例共享的——这也是为什么多个编辑器实例可以各自通过language选项使用不同语言,而无需重复导入语言文件。

二、语言文件目录结构

语言文件在项目开发、构建产物、npm 包和 CDN 四个阶段的存放位置各不相同,理解这些路径有助于定位文件与排查问题。

源码目录(供贡献者)

所有内置语言文件以 TypeScript 源码形式存放于:

apps/editor/src/i18n/ - en-us.ts - ko-kr.ts - zh-cn.ts - ...

每个文件的结构完全一致:先import Editor from '../editorCore',随后调用Editor.setLanguage(...)注册文案。以 apps/editor/src/i18n/ko-kr.ts 为例:

import Editor from '../editorCore'; Editor.setLanguage(['ko', 'ko-KR'], { Markdown: '마크다운', WYSIWYG: '위지윅', Write: '편집하기', Preview: '미리보기', // ... });

构建产物(供维护者)

构建后,语言文件会被编译为独立 JS 文件输出到apps/editor/dist/i18n/

apps/editor/dist/ - i18n/ - ko-kr.js - ...

npm 包内

安装@toast-ui/editor后,语言文件位于包内的dist/i18n/目录,这是日常开发中最常用的导入路径:

node_modules/@toast-ui/editor/dist/ - i18n/ - ko-kr.js - ...

CDN 分发

CDN 上同一份语言文件提供普通版与压缩版(.min.js),可直接通过<script>标签引入:

uicdn.toast.com/editor/latest/ - i18n/ - ko-kr.js - ko-kr.min.js - ...

三、内置语言与有效语言代码

下表列出了 TOAST UI Editor 内置提供的全部语言文件及其可用的语言代码。语言代码遵循 IETF language tag 规范;导入语言文件后,其注册的代码即可作为language选项的值。

语言名称i18n 文件注册代码
Arabicar.jsar
Chinese (S)zh-cn.jszh-CN
Chinese (T)zh-tw.jszh-TW
Croatian (Croatia)hr-hr.jshr|hr-HR
Czech (Czech Republic)cs-cz.jscs|cs-CZ
Dutch (Netherlands)nl-nl.jsnl|nl-NL
English (United States)en-us.jsen|en-US
Finnish (Finland)fi-fi.jsfi|fi-FI
French (France)fr-fr.jsfr|fr-FR
Galician (Spain)gl-es.jsgl|gl-ES
German (Germany)de-de.jsde|de-DE
Italian (Italy)it-it.jsit|it-IT
Japanese (Japan)ja-jp.jsja|ja-JP
Korean (Korea)ko-kr.jsko|ko-KR
Norwegian Bokmål (Norway)nb-no.jsnb|nb-NO
Polish (Poland)pl-pl.jspl|pl-PL
Portuguese (Brazil)pt-br.jspt|pt-BR
Russian (Russia)ru-ru.jsru|ru-RU
Spanish (Castilian, Spain)es-es.jses|es-ES
Swedish (Sweden)sv-se.jssv|sv-SE
Turkish (Turkey)tr-tr.jstr|tr-TR
Ukrainian (Ukraine)uk-ua.jsuk|uk-UA

重要说明:默认语言是英语。编辑器不会提供英语的生产语言文件(en-us.js),也无需导入该文件——en-US作为DEFAULT_CODE内置于核心,未导入任何语言文件时编辑器即呈现英文界面。这在源码中体现为I18n.get()在目标代码未注册时的en-US回退逻辑(apps/editor/src/i18n/i18n.ts)。

从源码看,各语言文件注册的代码与上表完全一致,例如中文简体(apps/editor/src/i18n/zh-cn.ts)只注册了'zh-CN'一个代码,而韩语(apps/editor/src/i18n/ko-kr.ts)同时注册了['ko', 'ko-KR']两个代码,因此language: 'ko'language: 'ko-KR'均有效。

四、导入语言文件:三种方式

使用任何非英语语言前,必须先导入对应的语言文件完成注册。下面代码中的${fileName}对应上表「i18n File」列的文件名(可省略扩展名)。

ES Modules(推荐)

import '@toast-ui/editor/dist/i18n/${fileName}';

例如导入韩语:

import '@toast-ui/editor/dist/i18n/ko-kr';

CommonJS

require('@toast-ui/editor/dist/i18n/${fileName}');

CDN<script>引入

通过 CDN 使用时,同样需要额外引入语言文件(提供压缩版):

<script src="https://uicdn.toast.com/editor/latest/i18n/${fileName}"></script>

仓库中的 i18n 示例页 apps/editor/examples/example16-i18n.html 展示了 CDN 引入方式:页面依次加载toastui-editor-all.jsi18n/ko-kr.js,随后用language: 'ko'创建编辑器;文件头部的注释也提示了 ESM 环境下应改为import '@toast-ui/editor/dist/i18n/ko-kr';

五、实际使用:三个典型场景

以下示例均基于 npm 安装方式。

场景一:基本用法——按实例指定语言

language选项的值对应上表「Registered Code」列,默认值为enen-US(两者等效,均指向内置的英文文案)。你可以让不同编辑器实例使用不同语言:

import Editor from '@toast-ui/editor'; // Step 1 : 导入语言文件(注册语言代码) import '@toast-ui/editor/dist/i18n/ko-kr'; // Step 2 : 为每个编辑器分别设置语言 const foo = new Editor({ // 未设置 language,使用默认英文 // ... }); const bar = new Editor({ // 使用韩语 // ... language: 'ko-KR', });

从 apps/editor/src/editorCore.ts 的默认选项可见language: 'en-US'即为内置默认值,实例创建时会被写入 I18n 单例。

场景二:局部覆盖——修改指定语言的某些文案

当内置文案不完全符合你的产品语境时,可调用静态方法Editor.setLanguage(code, data)覆盖特定语言代码下的部分键值。该方法会以「合并」而非「整体替换」的方式生效:源码中setLanguage对已存在的代码执行extend(langData, data)(apps/editor/src/i18n/i18n.ts),因此只需给出要修改的键即可。英文默认值可参考 apps/editor/src/i18n/en-us.ts。

import Editor from '@toast-ui/editor'; // Step 1 : 导入语言文件 import '@toast-ui/editor/dist/i18n/ko-kr'; // Step 2 : 覆盖指定语言的部分文案 Editor.setLanguage('en-US', { 'Add row': '[Add Row]', // 默认值是 'Add row' }); Editor.setLanguage('ko-KR', { 'Add row': '[로우 추가]', // 默认值是 '행 추가' }); // Step 3 : 为每个编辑器分别设置语言 const foo = new Editor({ // 使用默认英文 // ... }); const bar = new Editor({ // 使用韩语 // ... language: 'ko-KR', });

覆盖操作同样可以作用于尚未导入的内置语言:即使你只导入了ko-kr.js,先setLanguage('en-US', ...)也会把英文默认文案的对应键一并覆盖。

场景三:注册全新语言

如果目标语言不在内置列表中,可直接用setLanguage注册一个全新代码及其完整文案表,随后在language选项中直接使用:

import Editor from '@toast-ui/editor'; // Step 1 : 注册新语言 Editor.setLanguage('en-GB', { Markdown: '...', WYSIWYG: '...', // 其余键…… }); // Step 2 : 使用新注册的代码创建实例 const bar = new Editor({ // ... language: 'en-GB', });

注册时只需保证文案表包含所有 UI 会读取的键(完整键集见 apps/editor/src/i18n/en-us.ts),漏掉的键会在运行时触发There is no text key异常,因此建议以英文文件为模板逐键补全。

六、为仓库贡献新的语言文件

若希望为社区贡献一种内置列表之外的语言,可按以下流程操作(以泰语th-TH为例):

Step 1:添加语言源文件

Fork 仓库后,在源码目录新增语言文件,文件名遵循${languageCode}-${countryCode}.js约定,且languageCodecountryCode均使用小写(如en-gb.ts):

apps/editor/src/i18n/ - en-us.ts - ko-kr.ts - th-th.ts // 新增

Step 2:编写并注册文案

参照 apps/editor/src/i18n/en-us.ts 编写setLanguage调用的各参数值。第一个参数是映射到该语言文件的代码值,遵循${languageCode}-${countryCode}约定:languageCode小写、countryCode大写。

// th-th.js // ... Editor.setLanguage('th-TH', { Markdown: '...', WYSIWYG: '...', // ... });

Step 3(可选):省略国家代码的代码别名

当满足 IETF 语言标签规范时,可以额外注册不带国家代码的别名,让language选项既支持th-TH也支持th

  • 可选脚本与区域子标签在不能提供额外区分信息时应省略。例如西班牙语完全预期使用拉丁字母书写,es优于es-Latn;日语在日本的使用与其他地区差异不大,ja优于ja-JP
  • 并非所有语言区域都能用有效的区域子标签表示:主语言的次国家级地区方言以变体子标签注册。例如加泰罗尼亚语瓦伦西亚方言的变体子标签在 Language Subtag Registry 中以前缀ca注册,由于该方言几乎只在西班牙使用,区域子标签ES通常可以省略。
// th-th.js // ... Editor.setLanguage(['th', 'th-TH'], { Markdown: '...', WYSIWYG: '...', // ... });

源码中这种「一文件多代码」的写法已有大量先例:绝大多数内置语言都通过数组同时注册语言代码与「语言-国家」代码(如['ko', 'ko-KR']['zh-CN' 之外的 'cs', 'cs-CZ']等),而 apps/editor/src/i18n/ar.ts 仅注册了'ar',说明是否添加国家代码别名完全由语言文件作者按 IETF 规范决定。

七、验证与示例

仓库提供了可直接运行验证的 i18n 示例页 apps/editor/examples/example16-i18n.html:以 CDN 方式加载编辑器与ko-kr.js语言文件后,用language: 'ko'创建实例,即可观察工具栏提示(tooltip)等 UI 文案切换为韩语的效果——这也印证了「语言代码别名(ko)与完整代码(ko-KR)等效」的设计。

单元测试方面,apps/editor/src/test/unit/editor.spec.ts 覆盖了setLanguage()静态方法,验证其会正确转发到i18n.setLanguage,可作为理解「语言文件注册 → 全局文案表 → 实例生效」调用链的参考。

八、关键要点速查

  • 默认英文免导入en-US内置于核心,使用英文无需导入任何语言文件。
  • 先注册后使用:非英语语言必须先导入对应dist/i18n/下的文件,再在language选项中写注册代码。
  • 代码可带别名:多数语言同时注册了语言代码语言-国家代码(如koko-KR),两者皆可作为language值。
  • 覆盖与新建都走setLanguage:静态方法Editor.setLanguage(code, data)对已存在代码做键级合并覆盖,对不存在代码则整体注册。
  • 文案缺失会抛错:若当前语言缺少 UI 读取的某个键,i18n.get()会抛出There is no text key "...",自定义语言包务必以 apps/editor/src/i18n/en-us.ts 为模板补全。

【免费下载链接】tui.editor🍞📝 Markdown WYSIWYG Editor. GFM Standard + Chart & UML Extensible.项目地址: https://gitcode.com/gh_mirrors/tu/tui.editor

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/21 2:30:50

研发项目管理软件怎么选?12款主流工具横向对比与选型指南

做研发项目管理软件选型这件事&#xff0c;我前后经历过好几轮。从最初团队十来个人的时候大家挤在Excel里填进度&#xff0c;到现在几十号人并行推进多条产品线&#xff0c;工具换了好几茬&#xff0c;踩过的坑能写满一页纸。每次遇到团队问我“到底该用哪款研发项目管理软件”…

作者头像 李华
网站建设 2026/9/21 2:29:14

全渠道客服系统选型实战:畅远系统体验与避坑指南

做客服系统选型的这几个月&#xff0c;我被问得最多的一句话就是&#xff1a;“到底有没有靠谱的全渠道客服系统推荐&#xff1f;”问的人里有电商运营负责人&#xff0c;有SaaS公司的售后主管&#xff0c;也有刚把客服团队扩到三十人的创业公司老板。大家的需求其实都差不多&a…

作者头像 李华
网站建设 2026/9/21 2:26:35

企业在线学习与考试平台怎么选?四大产品深度对比

1. 先搞清楚四家平台各自的定位和适用场景说实话&#xff0c;市面上的企业在线学习与考试平台已经不少了&#xff0c;但真正把“学”和“考”两个环节同时做扎实的并不算多。泛微青蓝阁、考试星、酷学院、云学堂这四家&#xff0c;经常被放在一起比较&#xff0c;但这四家其实都…

作者头像 李华
网站建设 2026/9/21 2:26:07

Easy-Vibe 云原生基础:Kubernetes 编排原理与 kubectl 实战指南

Easy-Vibe 云原生基础&#xff1a;Kubernetes 编排原理与 kubectl 实战指南 【免费下载链接】easy-vibe 从 0 到 1 学会 vibe coding&#xff0c;项目制学习 项目地址: https://gitcode.com/datawhalechina/easy-vibe 导读 在 Easy-Vibe 的云计算与基础设施章节中&…

作者头像 李华
网站建设 2026/9/21 2:25:02

C语言实战:10个从语法到项目的小程序

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华