ToolJet国际化:多语言支持与本地化配置
在全球化应用开发中,多语言支持(国际化/Internationalization,简称i18n)是提升用户体验的关键环节。ToolJet作为一款面向全球用户的低代码平台,提供了完善的国际化架构,支持界面文本、错误提示、验证信息等内容的多语言切换。本文将详细介绍ToolJet的国际化实现机制、语言包结构及本地化配置方法,帮助开发者快速构建支持多语言的应用。
国际化架构概览
ToolJet的国际化系统基于前端资源文件与动态语言切换机制实现,核心包含三大模块:
- 语言资源管理:采用JSON格式存储各语言文本,支持模块化拆分与按需加载
- 语言切换引擎:通过上下文API管理当前语言状态,实现界面实时刷新
- 本地化工具链:提供文本提取、翻译校验、动态注入的完整工作流
其架构流程如下:
关键实现文件包括:
- 语言资源目录:frontend/assets/translations/
- 国际化上下文:src/_hooks/useTranslation.ts
- 语言切换组件:src/components/LanguageSelector.tsx
语言包结构解析
ToolJet采用层级化JSON结构组织语言资源,支持全局通用文本与模块专用文本分离管理。以英文语言包为例:
核心结构示例
{
"globals": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete"
},
"editor": {
"preview": "Preview",
"share": "Share",
"queries": "Queries"
},
"loginSignupPage": {
"emailAddress": "Email address",
"password": "Password",
"signIn": "Sign in"
}
}
模块化设计特点
-
命名规范:
- 采用PascalCase命名组件/页面模块(如
loginSignupPage) - 使用camelCase命名操作与状态(如
saveChanges) - 全局通用文本集中在
globals节点
- 采用PascalCase命名组件/页面模块(如
-
变量插值:支持动态文本替换,如:
"slack": { "connectToolJetToSlack": "{{whiteLabelText}} can connect to Slack..." } -
嵌套结构:按功能模块层级组织,减少命名冲突,如编辑器相关文本全部位于
editor节点下。
本地化实现步骤
1. 添加新语言包
在frontend/assets/translations/目录下创建语言文件,命名格式为[语言代码].json(如zh-CN.json),完整复制英文模板并进行翻译。以登录页面为例:
// zh-CN.json 片段
"loginSignupPage": {
"emailAddress": "电子邮箱",
"password": "密码",
"signIn": "登录",
"forgotPassword": "忘记密码",
"dontHaveAccount": "还没有账号?"
}
2. 配置语言切换器
修改语言选择组件,添加新语言选项:
// src/components/LanguageSelector.tsx
const languages = [
{ code: 'en', name: 'English' },
{ code: 'zh-CN', name: '简体中文' },
// 添加其他语言
];
3. 文本使用方法
在组件中通过useTranslation钩子获取翻译函数,实现文本国际化:
import useTranslation from '../_hooks/useTranslation';
const LoginForm = () => {
const { t } = useTranslation();
return (
<div>
<input placeholder={t('loginSignupPage.emailAddress')} />
<button>{t('globals.signIn')}</button>
</div>
);
};
4. 动态语言切换
通过修改国际化上下文的语言状态,实现界面无刷新切换:
// 语言切换逻辑
const { setLanguage } = useTranslation();
const handleLanguageChange = (code) => {
setLanguage(code);
localStorage.setItem('tooljet_language', code); // 持久化保存
};
高级应用技巧
日期与数字格式化
利用国际化API处理区域敏感数据:
const { i18n } = useTranslation();
const formattedDate = new Intl.DateTimeFormat(i18n.language).format(new Date());
const formattedNumber = new Intl.NumberFormat(i18n.language).format(12345);
复数规则处理
对于需要根据数量变化的文本,可结合工具函数实现:
// 语言包中定义复数形式
"notifications": {
"unread": "You have {{count}} unread notification",
"unread_plural": "You have {{count}} unread notifications"
}
// 复数处理函数
const getPluralText = (key, count) => {
const baseKey = count === 1 ? key : `${key}_plural`;
return t(baseKey, { count });
};
右-to-left (RTL) 语言支持
ToolJet通过CSS变量与RTL样式文件支持阿拉伯语等 RTL 语言:
- 添加RTL语言检测:
const isRTL = ['ar', 'he'].includes(i18n.language);
document.documentElement.dir = isRTL ? 'rtl' : 'ltr';
- 导入RTL样式:
/* src/_styles/rtl.css */
[dir="rtl"] .ml-4 { margin-right: 1rem; margin-left: 0; }
[dir="rtl"] .flex-row { flex-direction: row-reverse; }
最佳实践与注意事项
1. 翻译一致性
- 建立术语表(如"App"统一译为"应用"而非"应用程序")
- 保持操作按钮文本简洁(如"Save"统一译为"保存")
- 错误提示需包含具体操作指引,避免直译导致歧义
2. 性能优化
- 生产环境启用语言包压缩与Tree-Shaking
- 对大型语言包实施按需加载:
// 动态导入示例
const loadLanguage = async (code) => {
const translations = await import(`../assets/translations/${code}.json`);
i18n.addResourceBundle(code, 'translation', translations);
};
3. 测试验证
- 使用国际化测试工具检测未翻译文本:
npm run test:i18n - 验证所有语言下的文本溢出与布局错乱问题
- 检查RTL语言的镜像布局是否正确
常见问题解决
Q: 新增语言未在切换器中显示?
A: 检查语言选择组件的languages数组是否添加了新语言配置,确保语言代码与JSON文件名一致。
Q: 部分文本未翻译?
A: 运行npm run extract:i18n命令提取最新文本,检查控制台翻译缺失警告,或使用:
grep -r "t('" src/ | grep -v ".test."
查找未国际化的文本调用。
Q: 动态切换语言后样式错乱?
A: 检查是否正确设置了document.documentElement.dir属性,RTL语言需确保所有浮动、边距等样式已做镜像调整。
ToolJet的国际化架构设计兼顾了灵活性与可扩展性,通过本文介绍的方法,开发者可快速实现多语言支持,覆盖全球用户需求。完整国际化文档可参考官方指南:docs/user-management/internationalization.md。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



