html中i18n占位符需规范处理:避免硬编码插值,统一用框架绑定(如v-t、t());lang/dir须动态同步;复数/占位符须用icu格式;静态资源路径和svg文本也应纳入i18n流程。

HTML 中直接写 i18n 占位符会破坏构建流程
硬编码 {{msg.welcome}} 或 ${t('welcome')} 在 HTML 模板里,看似省事,实则让静态分析、提取工具(如 extract-i18n、lingui extract)无法识别字符串来源,导致 key 漏提、重复、上下文丢失。工程化要求所有可翻译文本必须有明确的、可追踪的声明点。
实操建议:
- 用框架绑定方式:Vue 用
v-t="'welcome'",React 用t('welcome')包裹文本节点,避免在 HTML 属性或纯文本中混用插值语法 - 属性文案单独处理:按钮的
title、aria-label不要靠 JS 动态拼接,统一走t('btn.submit.title') - 避免“伪国际化”写法:比如
data-i18n="welcome"这类自定义属性,多数提取工具不识别,除非你额外配解析规则
lang 属性和 dir 必须动态响应语言切换
只改文案不改 lang="en" 或 dir="ltr",会导致屏幕阅读器误读、CSS [dir="rtl"] 规则失效、字体 fallback 异常。这不是样式问题,是可访问性和排版基础。
实操建议:
- 在语言切换时,同步更新
document.documentElement.lang和document.documentElement.dir - 不要依赖 CSS-in-JS 或组件内
dir属性覆盖全局方向 —— 它们无法影响::placeholder、原生表单控件等 - RTL 语言(如阿拉伯语、希伯来语)需验证数字与 LTR 文本混合时的显示顺序,
dir="auto"在某些场景下反而更不可靠,优先显式设dir="rtl"
HTML 模板里的复数/性别/占位符必须用标准 ICU 格式
写成 "You have {{count}} message(s)" 或 `Hello ${name}!` 看似能跑,但没法支持阿拉伯语的 6 种复数形式、俄语的格变化、或中文“他/她/TA”的性别中立表达。工程化要求格式可被 formatjs、lingui 等工具直接编译和校验。
实操建议:
- 复数用
{count, plural, one {https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b message} other {https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b messages}},别手写条件判断 - 占位符命名保持语义:用
{userName}而非{p1},否则上下文丢失,翻译人员无法理解 - 嵌套消息(如链接内含文案)拆成独立 key,避免
t('login.link.text', { link: `@#@#@#@#@#@#@#@#@#@0` })—— 这种写法会让提取工具丢掉子 key,且 XSS 风险高
静态资源路径(图片、SVG、字体)也得走 i18n 分支
写死 src="/assets/icons/en/check.svg" 或用 en-GB 做文件名前缀,等于把本地化逻辑耦合进路径结构,后续加新语言就得手动复制目录、改引用、清缓存。真正工程化的做法是让资源路径也参与 key 解析。
实操建议:
- 把图标路径声明为翻译项:
t('icon.success')返回/icons/ar/check.svg,由 locale 决定 - 字体族名(如
font-family: 'Noto Sans Arabic')需随语言切换,不能只靠 CSS@font-facefallback,要主动注入style或 class - 避免在 HTML 里用
data-lang-src手动切图 —— 这类逻辑应下沉到组件或工具函数,而非模板层
最常被忽略的是 SVG 内联文本(比如 <text>Download</text>),它不属于 JS 字符串,也不会被提取工具扫描,必须用 <use></use> 引用外部 symbol,再通过 JS 注入翻译后文案。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











