跪拜 Guibai
← All articles
Frontend · Vue.js

Using Chinese Source Text as i18n Keys: A CLI Workflow That Lets LLMs Handle the Translation Grind

By 10coding ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

For teams that own their translations and want LLM help without a separate translation platform, this removes the key-to-source mapping overhead and builds review and validation into the CLI. It is a concrete alternative to semantic keys when source-text stability is acceptable and the team can tolerate the trade-off of changing a key every time the copy changes.

Summary

Most i18n setups use semantic keys like `features.localeFiles.title`, which separate code from copy and add a mapping layer. When the source language is Chinese and developers maintain translations themselves, a different pattern works better: pass the Chinese source string directly to `t()`. This makes code read as the copy, gives an LLM translator natural context, and lets the same Chinese phrase map to multiple translations via a `__TRANS_ID` suffix.

The `@10coding/i18n-trans` CLI automates the maintenance workflow around this idea. It statically scans `t()` calls with Babel, compares source and target locale JSONs for missing or extra keys, and can auto-fix with `--add` and `--remove` flags. The `trans` command sends untranslated units in batches of 20 to any OpenAI-compatible endpoint, validates the response for exact key matches and placeholder preservation, and marks AI output with a `⟦REVIEW⟧` prefix for human sign-off.

Takeaways
— Using source text as keys makes code and copy identical, so developers never need to jump between code and locale files.
— The key lookup order is: target locale with `__TRANS_ID` variant, then target locale without variant, then source locale, then the raw source string itself.
— The CLI reports missing source keys, unused source keys, missing target translations, and extra target keys; exit code 1 on missing keys allows CI gating.
— The `check --add --add-target --remove` command auto-adds missing source keys, creates `⟦TODO⟧` placeholders in target files, and removes extra keys.
— `trans` only sends untranslated units (missing, `⟦TODO⟧`, or equal to source) to an OpenAI-compatible API; default batch size is 20 and execution is serial.
— New AI translations get a `⟦REVIEW⟧` prefix by default; `--ignore` writes clean values directly.
— Responses are validated for exact key set, non-empty values, and identical interpolation placeholders (`{name}` / `{{name}}`) before being written back.
— The `__TRANS_ID` suffix distinguishes multiple translations of the same Chinese word, e.g., `删除` → `Delete` vs. `删除__TRANS_ID_remove` → `Remove`.
— The CLI supports i18next and vue-i18n runtime integration via config options like `keySeparator: false` and `messageResolver` for dot/slash-containing keys.
— The project targets Chinese-source projects where developers maintain translations; it is not designed for strict copy-translation separation or complex ICU rules.
Conclusions

Using source text as keys couples key stability to copy stability; every copy change becomes a key change that orphans existing translations, so teams with frequently rewritten UI text would see constant churn.

The approach deliberately skips a runtime package and only defines a contract, which sidesteps framework version fragmentation but shifts the burden of correct interpolation handling to the consuming app.

Batching LLM calls at 20 units with context and validation treats machine translation as an asynchronous review pipeline rather than a one-shot replacement, matching how cautious teams actually need to deploy AI output.

The `__TRANS_ID` mechanism solves the one-word-many-translations problem without inventing artificial semantic keys, but it relies on the developer manually specifying the variant argument at each call site.

Concepts & terms
__TRANS_ID
A suffix mechanism that lets the same source phrase be translated differently depending on context. For example, `删除` maps to `Delete` normally, but `删除__TRANS_ID_remove` maps to `Remove`. The variant is supplied as a second argument to `t()` or via an `__TRANS_ID` option.
⟦TODO⟧ / ⟦REVIEW⟧ markers
Prefixes written into target locale files to mark translation states. `⟦TODO⟧` means the key exists but translation is pending; `⟦REVIEW⟧` means an LLM produced the translation but it still needs human review before going live. Removing the marker confirms the translation.
Source text as key
An i18n pattern where the key in locale JSON is the actual copy in the source language (e.g., `"你好"`) rather than a symbolic identifier like `greeting.hello`. This makes the code itself readable as UI text and naturally supplies the source string to an LLM translator.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗