<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Judy Su</title>
    <description>The latest articles on DEV Community by Judy Su (@judy_su_c45f40f3c5982edaa).</description>
    <link>https://dev.to/judy_su_c45f40f3c5982edaa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3860149%2F46969c47-037e-4933-80b0-0d611f4392f9.png</url>
      <title>DEV Community: Judy Su</title>
      <link>https://dev.to/judy_su_c45f40f3c5982edaa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/judy_su_c45f40f3c5982edaa"/>
    <language>en</language>
    <item>
      <title>How to Translate JSON, XLIFF, po, strings and i18n Files Without Breaking Your Format</title>
      <dc:creator>Judy Su</dc:creator>
      <pubDate>Fri, 03 Apr 2026 23:06:08 +0000</pubDate>
      <link>https://dev.to/judy_su_c45f40f3c5982edaa/how-to-translate-json-xliff-po-strings-and-i18n-files-without-breaking-your-format-2d1f</link>
      <guid>https://dev.to/judy_su_c45f40f3c5982edaa/how-to-translate-json-xliff-po-strings-and-i18n-files-without-breaking-your-format-2d1f</guid>
      <description>&lt;h1&gt;
  
  
  How to Translate JSON, XLIFF, and i18n Files Without Breaking Your Format
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Posted under: Localization, Developer Tools, AI Translation&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you've ever shipped a multilingual app, you already know the pain.&lt;/p&gt;

&lt;p&gt;You export your &lt;code&gt;en.json&lt;/code&gt; file, paste it into Google Translate or DeepL, and get back... a blob of plain text. No keys. No structure. Just translated strings floating in a void, completely detached from the format your app expects. Now you have to manually reconstruct the file, re-match every key, and pray nothing got reordered.&lt;/p&gt;

&lt;p&gt;Or you go the enterprise route — a translation management system (TMS) with a $300/month minimum, a three-week onboarding process, and a dedicated "integration consultant." For a one-time product update or a small startup going global, that's overkill by a mile.&lt;/p&gt;

&lt;p&gt;There's a gap here, and it's a frustrating one. This article covers the practical options for translating structured files — JSON, XLIFF, Markdown, CSV, &lt;code&gt;.po&lt;/code&gt;, and more — and why preserving format is the part that actually matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why "just translate the text" doesn't work for i18n files
&lt;/h2&gt;

&lt;p&gt;When you're internationalizing an app, your strings live inside structured files. A React app might use a JSON file like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"onboarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"welcome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Welcome back, {{name}}!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Continue to dashboard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"skip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Skip for now"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"errors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Connection failed. Please try again."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your session has expired."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Translating this file has some non-obvious requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keys must be preserved exactly.&lt;/strong&gt; Your app references &lt;code&gt;onboarding.welcome&lt;/code&gt; — if the translator renames it or flattens the structure, your app breaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Placeholders must survive untouched.&lt;/strong&gt; &lt;code&gt;{{name}}&lt;/code&gt; is code, not text. A translator who doesn't know this will turn it into &lt;code&gt;{{nombre}}&lt;/code&gt; or drop it entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nesting must be maintained.&lt;/strong&gt; Nested JSON is not the same as flat JSON. A file that loses its hierarchy will throw errors at runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The file must be valid after translation.&lt;/strong&gt; Malformed JSON (missing commas, unescaped quotes) causes hard failures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The same logic applies to XLIFF files, which are used by Xcode, Phrase, Crowdin, Smartling, and Articulate Rise — among many others. XLIFF is XML-based, which means misplaced tags or broken attributes silently corrupt your translation file. &lt;code&gt;.po&lt;/code&gt; files for Gettext, Android XML, &lt;code&gt;.arb&lt;/code&gt; files for Flutter, &lt;code&gt;.strings&lt;/code&gt; for iOS — they all carry structure that generic translation tools destroy.&lt;/p&gt;




&lt;h2&gt;
  
  
  The options, honestly evaluated
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: Manual translation via a freelancer or agency
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; legal documents, marketing copy, anything where nuance is critical&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Worst for:&lt;/strong&gt; structured files with lots of strings, fast turnaround, variable volume&lt;/p&gt;

&lt;p&gt;Freelancers and agencies work in CAT tools designed for human translators, not for structured file formats. The file gets handed off, worked on in a translation environment, and handed back — usually in the same format. But the cost scales with word count and language pair, turnaround is days to weeks, and coordinating across 5+ languages requires real project management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: Enterprise TMS (Phrase, Crowdin, Smartling, Lokalise)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; large teams with ongoing localization pipelines&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Worst for:&lt;/strong&gt; small teams, one-time projects, startups without a localization budget&lt;/p&gt;

&lt;p&gt;These platforms are excellent and battle-tested. They support every file format, have GitHub integrations, built-in machine translation, glossaries, and QA checks. They also start at $150–300/month before you've translated a single string, require weeks of setup, and assume you have a dedicated localization program manager.&lt;/p&gt;

&lt;p&gt;If you're a solo developer shipping a side project in 5 languages, this is not your tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 3: Google Translate / DeepL with copy-paste
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; casual phrases, quick checks, understanding foreign content&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Worst for:&lt;/strong&gt; anything structured&lt;/p&gt;

&lt;p&gt;You already know this doesn't work. You paste in your JSON, the structure disappears, and you spend the next hour reformatting. These tools are built for human-readable text, not machine-readable files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 4: Writing a script with the OpenAI or Claude API
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; developers comfortable with Python/Node, teams with engineering bandwidth&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Worst for:&lt;/strong&gt; non-technical users, teams that need it now&lt;/p&gt;

&lt;p&gt;This is the DIY approach: write a parser, extract strings, send them to an LLM in batches, reassemble the output, validate the file. Done well, this works great. But it takes time to build, maintain, and debug — especially when you're handling edge cases like placeholder preservation, nested structures, and RTL language support.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually solves the format problem
&lt;/h2&gt;

&lt;p&gt;The key insight is that the hard part of i18n file translation isn't the translation itself — modern AI models (Claude, GPT-4o, Gemini) do that very well. The hard part is &lt;strong&gt;round-tripping the file format&lt;/strong&gt;: extracting translatable strings, sending them through the model, and reassembling the result into an identical structure with only the text values changed.&lt;/p&gt;

&lt;p&gt;A tool that does this correctly will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parse the source file to extract only the text strings (not keys, not placeholders, not tags)&lt;/li&gt;
&lt;li&gt;Batch strings efficiently to minimize API costs&lt;/li&gt;
&lt;li&gt;Preserve all non-translatable content (interpolation variables, HTML tags, format codes)&lt;/li&gt;
&lt;li&gt;Validate the output file before returning it&lt;/li&gt;
&lt;li&gt;Return a file in exactly the same format as the input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://summontranslator.com" rel="noopener noreferrer"&gt;Summon Translator&lt;/a&gt;&lt;/strong&gt; is built around this exact problem. You upload a file — JSON, XLIFF, Markdown, CSV, &lt;code&gt;.po&lt;/code&gt;, &lt;code&gt;.strings&lt;/code&gt;, Android XML, &lt;code&gt;.arb&lt;/code&gt;, &lt;code&gt;.properties&lt;/code&gt;, or a scanned PDF — pick your target languages and AI model, and download translated files in the same format you uploaded. No reformatting. No copy-pasting. No manual reconstruction.&lt;/p&gt;

&lt;p&gt;The model choice matters: you can pick Claude Sonnet for high-quality nuanced translation, GPT-4o Mini for cost efficiency, Gemini 2.0 Flash for speed, or DeepSeek for budget-conscious bulk runs. The platform shows you the exact cost before anything runs, so there are no surprise bills.&lt;/p&gt;

&lt;p&gt;For a mobile app update with 500 strings across 5 languages, the total cost is around $27. For a 12-document hospital consent form package across 4 languages, around $89. Pay-per-use, no subscription required.&lt;/p&gt;




&lt;h2&gt;
  
  
  A practical walkthrough: translating a React i18n JSON file
&lt;/h2&gt;

&lt;p&gt;Here's what the flow looks like for a typical developer use case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Starting point:&lt;/strong&gt; You have &lt;code&gt;en.json&lt;/code&gt; with your English strings and need Spanish, French, German, and Japanese versions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Upload &lt;code&gt;en.json&lt;/code&gt; to Summon Translator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Select target languages — Spanish (ES), French (FR), German (DE), Japanese (JP).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Choose your AI model. For product UI strings, Claude Sonnet or GPT-4o gives the most natural-sounding output. If you're translating a large file and cost is a priority, GPT-4o Mini or Gemini Flash work well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Review the cost preview. For 500 strings across 4 languages, you're looking at roughly $5–8 depending on model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; Download. You get back &lt;code&gt;es.json&lt;/code&gt;, &lt;code&gt;fr.json&lt;/code&gt;, &lt;code&gt;de.json&lt;/code&gt;, &lt;code&gt;ja.json&lt;/code&gt; — all in the same structure as your input, with all keys intact, all placeholders preserved, all nesting maintained.&lt;/p&gt;

&lt;p&gt;Total time: under 5 minutes. No engineering work beyond the upload.&lt;/p&gt;




&lt;h2&gt;
  
  
  XLIFF-specific considerations
&lt;/h2&gt;

&lt;p&gt;XLIFF (XML Localization Interchange File Format) deserves a separate mention because it's the standard for most professional localization workflows — and it's where format-preservation matters most.&lt;/p&gt;

&lt;p&gt;An XLIFF file contains &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;target&amp;gt;&lt;/code&gt; elements, wrapped in &lt;code&gt;&amp;lt;trans-unit&amp;gt;&lt;/code&gt; tags with attributes like &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;resname&lt;/code&gt;, and &lt;code&gt;approved&lt;/code&gt;. A correct XLIFF translation populates the &lt;code&gt;&amp;lt;target&amp;gt;&lt;/code&gt; elements while leaving everything else untouched. An incorrect one might:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Translate the &lt;code&gt;id&lt;/code&gt; attribute (breaking the file)&lt;/li&gt;
&lt;li&gt;Modify &lt;code&gt;&amp;lt;ph&amp;gt;&lt;/code&gt; (placeholder) tags&lt;/li&gt;
&lt;li&gt;Drop &lt;code&gt;&amp;lt;mrk&amp;gt;&lt;/code&gt; (markup) elements&lt;/li&gt;
&lt;li&gt;Change the XML declaration or encoding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools like Xcode, Phrase, and Articulate Rise 360 are strict about this. If the XLIFF isn't well-formed or if structural elements have been altered, the import will fail — sometimes silently.&lt;/p&gt;

&lt;p&gt;Summon Translator handles XLIFF by parsing the XML structure and operating only on the text content of &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; elements, leaving all tags, attributes, and structural elements intact in the output. For eLearning content built in Articulate Rise, this is particularly relevant — the exported XLIFF from Rise has complex tag nesting that breaks most generic approaches.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to use which approach
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One-time file, small word count&lt;/td&gt;
&lt;td&gt;Summon Translator (free trial)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ongoing pipeline, large team&lt;/td&gt;
&lt;td&gt;TMS (Phrase, Crowdin, Lokalise)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marketing copy, legal documents&lt;/td&gt;
&lt;td&gt;Human translator + CAT tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer with time to build&lt;/td&gt;
&lt;td&gt;Custom LLM script&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quick check, no structure needed&lt;/td&gt;
&lt;td&gt;DeepL / Google Translate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;The localization tooling market has a huge gap between "paste text into DeepL" and "implement a full TMS." Most developers and small teams live in that gap — they need structured file translation that preserves format, costs per-use rather than per-month, and takes minutes rather than days.&lt;/p&gt;

&lt;p&gt;If you're in that gap, &lt;a href="https://summontranslator.com" rel="noopener noreferrer"&gt;Summon Translator&lt;/a&gt; offers 1,000 words free to try it — no credit card required, use code &lt;strong&gt;1TIME&lt;/strong&gt; at checkout.&lt;/p&gt;

&lt;p&gt;Upload your JSON. Get your JSON back. Translated.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: i18n, localization, JSON translation, XLIFF, file translation, AI translation, developer tools, internationalization&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Summon Translator</title>
      <dc:creator>Judy Su</dc:creator>
      <pubDate>Fri, 03 Apr 2026 22:33:12 +0000</pubDate>
      <link>https://dev.to/judy_su_c45f40f3c5982edaa/summon-translator-35o1</link>
      <guid>https://dev.to/judy_su_c45f40f3c5982edaa/summon-translator-35o1</guid>
      <description>&lt;p&gt;AI translation quality is solved. Format preservation isn't. This covers how to translate GitHub PR descriptions and review comments while keeping markdown, code blocks, and technical terminology intact. -&amp;gt; summontranslator.com OpenClaw friendly :)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>i18n</category>
      <category>webdev</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Translating GitHub PRs with Google Translate strips all the markdown. Inline comments have to be pasted one by one. I built a tool that translates PR i18n files markdown, json, xliff intact, technical terms handled correctly. -&gt; SummonTranslator.com</title>
      <dc:creator>Judy Su</dc:creator>
      <pubDate>Fri, 03 Apr 2026 22:31:00 +0000</pubDate>
      <link>https://dev.to/judy_su_c45f40f3c5982edaa/translating-github-prs-with-google-translate-strips-all-the-markdown-inline-comments-have-to-be-264n</link>
      <guid>https://dev.to/judy_su_c45f40f3c5982edaa/translating-github-prs-with-google-translate-strips-all-the-markdown-inline-comments-have-to-be-264n</guid>
      <description></description>
      <category>localization</category>
      <category>i18n</category>
      <category>ai</category>
      <category>claude</category>
    </item>
  </channel>
</rss>
