원클릭으로
i18n
给 web/ 前端组件接入多语言(中英)。当用户说加多语言、国际化、i18n、翻译、某页面没翻译、硬编码中文时触发。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
给 web/ 前端组件接入多语言(中英)。当用户说加多语言、国际化、i18n、翻译、某页面没翻译、硬编码中文时触发。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
恢复上下文。在 /clear 后或新 session 开始时使用。当用户说恢复上下文、继续之前的工作、catchup 时触发。
审查当前 git diff 中的 Go 代码。当用户说审查 Go 代码、review Go、检查代码时触发。
运行 Go 测试并分析结果。当用户说跑测试、运行测试、go test 时触发。
在已有 go-zero 服务里新增一个 HTTP 接口。当用户说加接口、新增 api、加路由时触发。
新增数据库模型/表。当用户说加表、新增 model、加数据库字段时触发。
在已有 go-zero 服务里新增一个 RPC 方法。当用户说加 rpc 方法、新增 grpc、新加 proto 接口时触发。
| name | i18n |
| description | 给 web/ 前端组件接入多语言(中英)。当用户说加多语言、国际化、i18n、翻译、某页面没翻译、硬编码中文时触发。 |
给 web/ 前端的用户可见文本接入多语言。本项目不用 react-i18next,也没有 web/src/i18n/locales/*.json(CLAUDE.md / frontend.md 里那句已过时,以本文为准)。
web/src/lib/i18n.ts —— 一个扁平对象 dict['zh-CN'] / dict['en'],key 用点号命名(如 trend.publish)。t(key, lang),缺失时回退 zh-CN,再回退 key 本身。不支持占位符插值。web/src/hooks/use-i18n.ts 的 useT(),返回 (key) => translate(key, lang),lang 来自 useSettingsStore(s => s.language)。.replace(),例如 t('trend.imageLimit').replace('{count}', String(n))。cd web
# 列某组件里所有非注释的中文行
grep -nE "[一-鿿]" src/components/im/Xxx.tsx | grep -vE "^\s*[0-9]+:\s*(//|/\*|\*)"
逐条判断是否用户可见(按钮/标题/placeholder/title/toast/空态/确认弹窗都算)。不该翻译的:语言名本身(简体中文 / English)、代码注释、日志、接口字段名。
lib/i18n.ts 加 key在 zh-CN 块末尾和 en 块末尾各加一组,分组写注释,两边 key 必须一一对应:
// zh-CN 块
'xxx.title': '我的相册',
'xxx.itemCount': '{count} 项',
// en 块
'xxx.title': 'Album',
'xxx.itemCount': '{count} items',
trend.* / fav.* / pe.* / sec.* / upc.* 等)。common.save/cancel/confirm/back/loadMore、时间 group.time.justNow/minutesAgo/hoursAgo/monthDay、在线 chat.online/offline。useTimport { useT } from '@/hooks/use-i18n';
export default function Xxx() {
const t = useT(); // 必须在所有 early return 之前(Hooks 规则)
...
<span>{t('xxx.title')}</span>
<input placeholder={t('xxx.search')} />
toast.success(t('xxx.saved'));
<div>{t('xxx.itemCount').replace('{count}', String(n))}</div>
}
每个子组件都要各自 const t = useT() —— 子组件拿不到父组件的 t。
cd web && npx tsc --noEmit -p tsconfig.json 2>&1 | grep <你改的文件名>
# 再确认无残留(排除注释/语言名/兜底)
grep -nE "[一-鿿]" src/components/im/Xxx.tsx | grep -vE "//|/\*|\*|简体中文"
预存的既有报错(如 aspectSquare/ringColor)与本次无关,只看自己文件。
const TYPE_MAP = {1:{label:'文本'}}):函数体外拿不到 t。把 label:'文本' 改成 labelKey:'trend.type.text',渲染时 t(cfg.labelKey)。fmtTime / getUserName):加一个 t 参数 fmtTime(date, t),所有调用点传进去。.map(t => ...)、const t = list.find(...) 会把翻译函数 t 遮蔽。重命名迭代/局部变量(tr / ty),别动翻译函数名。useT() 不能放在 if (!open) return null 之后。你的数据将<strong>永久删除</strong> 这种,拆成 t('a')<strong>{t('b')}</strong>t('c') 三段 key。perl -0pi -e "s/.../.../g"(不要加 -CSD,否则中文字节与解码不匹配会全部 miss)。t() 包裹,不许硬编码中文。zh-CN 与 en 两边 key 必须对齐,缺一边会回退中文。frontend.md)。feat: / fix:),英文,无署名。