locli 配合編碼智能體處理從混亂鍵名到核准翻譯的本地化流程
I let my coding agent do the whole localization job, from messy keys to approved translations
開發者 Mario Hahn 建立 locli,讓 Claude Code、Cursor 和 Codex 等編碼智能體協助完成應用程式本地化,從整理跨平台字串鍵名、合併重複鍵到翻譯,並由人手核准後才寫入應用程式。
Every app I ship exists on iOS and Android, some on the web too. After a few releases the
strings were a mess:
- half of them hard-coded in SwiftUI views and Compose screens
- the rest in
Localizable.xcstringsunder keys like"Sign in",account.loginandlogin_button, all for the same button - the Android app with its own names for everything (
R.string.login_btn) - the web app with a third set (
auth.signIn)
Three names for one text means three translations, three chances to drift, and nobody knows
which one is right.
What I wanted
Say "localize this app" to my coding agent, and get it done properly: not a quick
translation that breaks a placeholder or puts a German sentence into a toolbar button.
So I built locli, and now this is what my agent (Claude Code, but Cursor
and Codex work the same) does on its own.
1. Move every text into the catalog
Hard-coded strings go into the app's own catalog: the String Catalog on iOS, strings.xml on
Android, ICU JSON on the web or backend. The code switches to looking them up by key.
2. One identifier per meaning, on every platform
Every text gets one lower_snake_case identifier with a feature prefix:
account_login
settings_language_title
cart_checkout
The same identifier on iOS, Android and web. So "Sign in" is one key, translated once,
used everywhere. Where a platform really needs different wording, it gets a variant of that
key instead of a new one.
3. Merge the duplicates
This is the part I used to dread. The agent finds keys that mean the same thing
(account.login on iOS, account_login on Android), merges them into one, keeps every
translation, and switches the code to the new name.
It only stops and asks me where two values really conflict, for example two different German
texts for the same button. It never just picks one.
4. Translate, with context
locli push uploads the keys and texts (it never overwrites what a translator changed). Then
the agent translates, using:
- the project's tone per language and a glossary ("workspace", never "project")
-
where each text is used:
locli contextreads the code and knows thatcart_checkoutis a toolbar item andcart_titlea screen title
Every upload is checked: placeholders like %lld or {count} in every language, plural forms
per language (Polish and Arabic need more than "one" and "other"), glossary terms.
5. I approve, then it ships
The one thing the agent can't do is ship. I go through the changed texts in the locli web app,
each with a diff, and approve the release. Only then does locli pull write exactly that
release into the app. Builds stay reproducible, and a bad translation never reaches the store
just because an agent was confident.
Six apps in
I run six of my own apps on it, about 2,650 keys across iOS, Android, web and backend, and
locli localizes its own web app. Dogfooding found real bugs, and each got a fix and a test:
current Xcode saves String Catalogs as version 1.1, which the CLI refused at first.
Try it
In your app's repository:
npx @locli/cli init
or tell your agent: "Set up locli for this app's texts."
For Claude Code there's a plugin:
/plugin marketplace add mariohahn/locli
/plugin install locli@locli
The CLI and MCP server are MIT and have no dependencies:
github.com/mariohahn/locli. One project is free.
I'd love to hear how messy your keys are, and where this breaks on your project.
來源:DEV Community · dev.to
