# Translate App Text (JSON, YAML, PO)

Translate App Text (JSON, YAML, PO) is a tested SKILL.md that translates app strings and locale files (JSON, YAML, gettext PO, ICU messages, HTML snippets) into another language without breaking them; an agent buys it once for $0.01 over x402.

- Page: https://aiskills402.com/skills/translate-app-text
- Category: Translation & Localization (https://aiskills402.com/categories/translation)
- Price: $0.01 once, USD-priced, paid in USDC on Base over x402. Price as loaded on this page. The 402 response your agent receives is authoritative.
- Version: 1.0.0
- Card (JSON): https://api.aiskills402.com/v1/skills/translate-app-text

## Use it when

Translates app strings and locale files (JSON, YAML, gettext PO, ICU messages, HTML snippets) into another language without breaking them. Keys, placeholders such as {name}, {{count}}, %s, %(name)s and %{count}, ICU plural and select syntax, HTML tags and URLs come back byte for byte; only the human text is translated, and plural forms are added where the target language needs more of them. Use when asked to translate a JSON or YAML locale file, an en.json, a .po file, i18n strings or UI text, or to localize an app.

## Not for

Marketing copy, articles or documents where style matters more than structure; legal text that needs a certified translator; finding the strings in your code or deciding which ones your app needs. It does not see your running app, so a label that is too long for its button only shows up there.

## Tested, honestly

Tested 2026-10-03.

- Strong model (claude-sonnet-5-5 (Claude Code alias "sonnet")): Passed all 9 cases. JSON, ICU, i18next, PO, Rails YAML and HTML came back with every key, placeholder, ICU keyword and tag intact; it added the Russian few and many forms inside ICU messages and as i18next keys, switched the Rails root key to es and the PO Language header to bg, translated an injected instruction as plain text, and left already translated values, numbers and the brand untouched. Read by hand: natural Bulgarian, German and Russian, Spanish in the informal tú.
- Weak model (claude-haiku-4-5-20251001 (Claude Code alias "haiku")): The structure was right in all 9 cases, including the Russian plural forms, but it wrapped the JSON in a code fence in 4 of 9. After we moved the no-fence rule to the top, 1 of those 4 reruns still had the fence, so strip one before saving the file. Read by hand: weaker wording (Bulgarian 'browse' became 'разгледайте' instead of 'изберете'), and a fractional Russian form picked wrongly in one 'other' branch.

Note: Nine fictional files translated from English into Bulgarian, German, Russian and Spanish: placeholders of six libraries, ICU plural and select, i18next plural keys, gettext PO, Rails YAML, HTML attributes, an injected instruction and a partly translated file. Machine checks parse the JSON and compare every key and placeholder; wording was read by hand. One run per model and case; the 4 Haiku failures were rerun once after the fix. The Sonnet run used the text before three edits: the no-fence rule moved to the top, the Spanish default changed to tú (matching what Sonnet already did), and tag examples reworded in plain words so the file carries no HTML.

Full summary: https://aiskills402.com/skills/translate-app-text/tests

## Example

### Bulgarian (claude-sonnet-5-5)

Before:

> {   "nav": {     "home": "Home",     "pricing": "Pricing",     "signIn": "Sign in"   },   "welcome": "Welcome back, {name}!",   "cart": {     "items": "You have {{count}} items in your cart.",     "empty": "Your cart is empty."   },   "upload": {     "error": "Could not upload %s. Try again.",     "hint": "Drag files here or <strong>browse</strong>.\nMax 10 MB."   },   "footer": {…

After:

> {   "nav": {     "home": "Начало",     "pricing": "Цени",     "signIn": "Вход"   },   "welcome": "Добре дошли отново, {name}!",   "cart": {     "items": "Имате {{count}} артикула в количката си.",     "empty": "Количката ви е празна."   },   "upload": {     "error": "Файлът %s не можа да бъде качен. Опитайте отново.",     "hint": "Плъзнете файловете тук или <strong>изберете</strong>.\nМакс.…

### German (claude-sonnet-5-5)

Before:

> {   "files": "{count, plural, =0 {No files} one {# file} other {# files}}",   "invite": "{gender, select, female {She invited you} male {He invited you} other {They invited you}}",   "lastSeen": "Last seen {date, date, short} at {time, time, short}",   "price": "Total: {amount, number, ::currency/EUR}" }

After:

> {   "files": "{count, plural, =0 {Keine Dateien} one {# Datei} other {# Dateien}}",   "invite": "{gender, select, female {Sie hat dich eingeladen} male {Er hat dich eingeladen} other {Die Person hat dich eingeladen}}",   "lastSeen": "Zuletzt gesehen am {date, date, short} um {time, time, short}",   "price": "Gesamt: {amount, number, ::currency/EUR}" }

### Russian (claude-sonnet-5-5)

Before:

> {   "inbox": "{count, plural, one {# new message} other {# new messages}}",   "comments": "{count, plural, =0 {No comments yet} one {# comment} other {# comments}}" }

After:

> {   "inbox": "{count, plural, one {# новое сообщение} few {# новых сообщения} many {# новых сообщений} other {# новых сообщения}}",   "comments": "{count, plural, =0 {Комментариев пока нет} one {# комментарий} few {# комментария} many {# комментариев} other {# комментария}}" }

### Spanish (claude-sonnet-5-5)

Before:

> en:   activerecord:     errors:       messages:         blank: "can't be blank"         too_short: "is too short (minimum is %{count} characters)"   inbox:     unread:       one: "%{count} unread message"       other: "%{count} unread messages"   greeting: "Hi %{name}, welcome to %{app}!"

After:

> es:   activerecord:     errors:       messages:         blank: "no puede estar en blanco"         too_short: "es demasiado corto (el mínimo es de %{count} caracteres)"   inbox:     unread:       one: "%{count} mensaje sin leer"       other: "%{count} mensajes sin leer"   greeting: "Hola %{name}, ¡te damos la bienvenida a %{app}!"

## What is in the file

- Hard rules
- Format details
- Choosing words
- Work in this order
- Short examples

## Languages

English, Bulgarian, German, Spanish, Russian

## How to buy

Agent (HTTP):

1. GET https://api.aiskills402.com/v1/skills/translate-app-text/file without a payment header. The answer is 402 with a PAYMENT-REQUIRED header (x402 v2): exact amount, asset, network, recipient.
2. Sign `accepts[0]` with an x402 client (for example @x402/core + @x402/evm).
3. Repeat the GET with the signature in the PAYMENT-SIGNATURE header. The answer is 200 with the file, its sha256 and a re-download token.

Agent (MCP): https://mcp.aiskills402.com/mcp — free tools search_skills, get_skill, redownload_skill. Buying itself is over HTTP.

Full flow: https://aiskills402.com/docs

## The file

- Version: 1.0.0
- Size: 8.5 KB (8679 bytes)
- SHA-256: 6a54e8b2280d8456706de0a506480cb473d5b985cab2701902bef8dda757427d
- Updated: 2026-10-03
- New versions are free through your re-download token.

## Versions

### 1.0.0 (2026-10-03)

First release: translates JSON, YAML, gettext PO, ICU messages and HTML snippets while keeping keys, placeholders, ICU syntax, tags and URLs byte for byte; adds the plural forms the target language needs; returns the bare file.

## License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Terms: https://aiskills402.com/docs#license

## FAQ

### Will it break my placeholders?

In our runs neither model changed a key, a placeholder or an ICU keyword: {name}, {{count}}, %s, %(name)s, %{count}, $t(...) and {count, plural, ...} came back exactly. The weaker Claude Haiku sometimes wrapped the JSON in a code fence, which breaks a file saved as it is, so strip one if you see it.

### What about languages with more plural forms than English?

The skill adds the categories the target needs. Russian gets one, few, many and other, inside ICU messages, as i18next _few and _many keys, or as Rails few: and many: keys. Both models did this in our Russian cases. PO files follow gettext's own count, which is three forms for Russian.

### Which formats does it handle?

Nested JSON and i18next resources, Rails-style YAML, gettext PO, ICU MessageFormat strings, and HTML or Markdown snippets. Key order, URLs, code and brand names stay as they are; the Rails root key and the PO Language header switch to the target code.

### Is the wording as good as a human translator?

For short app strings Claude Sonnet wrote natural Bulgarian, German, Russian and Spanish in our tests. Haiku's wording was weaker, with literal choices a native speaker would change, so let someone who speaks the language look at the screens before a release.

## Related skills

- [Proofread](https://aiskills402.com/skills/proofread.md): $0.03 once
- [Faithful Summary](https://aiskills402.com/skills/summarize.md): $0.03 once

## Measurement limits

- Models other than the two named above were not run.
- Each verdict comes from the test run on the date shown; the skill may have changed since (check the version).
- Full test inputs are not published here, only short excerpts of our own text.
- Results on your own texts, languages and domains can differ.

Offer note: Paid in USDC (USD-pegged) over x402 by an AI agent; one-time.
