Translating a JSON localization file sounds trivial until the first run corrupts your structure. Keys get translated, nested objects flatten, arrays lose their order, and placeholders like {username} come back mangled. If you want to translate JSON via API reliably, you need a strategy that treats structure as sacred and touches only the values. This guide walks through the failure modes and a clean, production-ready approach.
Why Translating JSON Breaks Things
A JSON file is a tree of keys and values. Translation should only ever change the human-readable values, but naive approaches routinely damage everything else:
- Translated keys. If you stringify the whole object and send it to a plain text endpoint, the API happily translates your keys too. "title" becomes "titre", and your app can no longer find its strings.
- Broken nesting. Deeply nested objects and arrays get flattened or reordered when the response is not parsed back into the original shape.
- Destroyed placeholders. Variables like {username}, %s, or {{count}} get "translated" or spaced out, so runtime interpolation fails.
- Corrupted JSON syntax. Quotes, braces, and commas passed as raw text can come back subtly altered, producing invalid JSON.
The fix is to separate the values from the structure, translate the values, and reassemble.
The Safe Approach, Step by Step
Step 1: Translate values only, never keys
Walk the object and collect only the string values. Keys are identifiers, not content — they must survive untouched. If your API translates raw text, extract values first; if it offers native JSON translation, it should preserve keys automatically. AIbit Translator supports native JSON translation, parsing the tree and translating only the values while keeping every key intact.
Step 2: Handle nested objects and arrays
Real localization files are deeply nested. Your traversal must recurse into nested objects and iterate arrays, translating string leaves wherever they appear while rebuilding the exact same shape. A recursive walk that returns a new tree of identical structure is the reliable pattern. Preserve array order — index position often carries meaning in UI lists.
Step 3: Protect placeholders and variables
Interpolation tokens must pass through verbatim. Before translating, mask tokens such as {username}, {{count}}, %s, or %1$d so the engine leaves them alone, then restore them afterward. Many teams replace each token with a neutral sentinel, translate, and swap the originals back. A markup-aware API that recognizes common placeholder syntaxes removes most of this work.
Step 4: Validate the output
After translation, parse the result and assert that the key set is identical to the source and that every placeholder present in the source still exists in the translation. Fail the build if a key went missing or a token vanished. This one check catches the overwhelming majority of localization regressions before they ship.
Example: Translating JSON with curl
Here is a minimal request that sends a JSON payload to a translation endpoint. The API translates the values and returns the same structure with keys preserved.
curl -X POST "https://aibit-translator.p.rapidapi.com/api/v1/translator/json" \
-H "Content-Type: application/json" \
-H "X-RapidAPI-Key: YOUR_API_KEY" \
-d '{
"from": "en",
"to": "fr",
"json": {
"welcome": "Hello, {username}",
"buttons": { "save": "Save", "cancel": "Cancel" },
"items": ["First item", "Second item"]
}
}'
The response keeps welcome, buttons.save, buttons.cancel, and the items array exactly where they were — only the readable strings change, and {username} stays intact.
Example: Translating JSON with JavaScript fetch
The same call from a Node or browser environment. Note the use of JSON.stringify and string concatenation so there is no ambiguity in the payload.
const source = {
from: "en",
to: "fr",
json: {
welcome: "Hello, {username}",
buttons: { save: "Save", cancel: "Cancel" },
items: ["First item", "Second item"]
}
};
fetch("https://aibit-translator.p.rapidapi.com/api/v1/translator/json", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-RapidAPI-Key": "YOUR_API_KEY"
},
body: JSON.stringify(source)
})
.then(function (res) { return res.json(); })
.then(function (data) {
console.log("Translated:", data);
})
.catch(function (err) {
console.error("Translation failed:", err);
});
Because the endpoint understands JSON natively, you send the object as-is and receive the same shape back. There is no manual value extraction, no key protection code, and no reassembly step to maintain.
A note on batching
For large files, send the whole object in one call rather than one request per string. Fewer round trips means lower latency and fewer chances for partial failures to leave your file half-translated. With sub-200ms responses, a single batched JSON call typically finishes faster than dozens of individual string calls.
Common Pitfalls to Avoid
- Do not join values into one blob. Concatenating strings with a delimiter and splitting later breaks the moment the translation changes the delimiter or word order.
- Do not translate numeric or boolean-like values. Skip anything that is not a genuine human-readable string.
- Do not skip validation. Always diff the key sets and placeholder sets between source and output before merging.
Get Started
Translating JSON correctly comes down to one rule: change the values, never the structure. An API with native JSON translation does the traversal, key preservation, and placeholder handling for you, so you can localize a full file with a single request. AIbit Translator supports native JSON and HTML translation across 240+ languages with sub-200ms latency and a free tier to test with. See the docs and get an API key at aibitranslator.com.