{"id":295,"date":"2026-06-11T15:16:56","date_gmt":"2026-06-11T15:16:56","guid":{"rendered":"https:\/\/www.forethought-studio.com\/translate\/resx\/"},"modified":"2026-06-11T18:13:52","modified_gmt":"2026-06-11T18:13:52","slug":"resx","status":"publish","type":"page","link":"https:\/\/www.forethought-studio.com\/translate\/resx\/","title":{"rendered":".NET .resx translator that runs in your browser"},"content":{"rendered":"<p class=\"dft-page-lede\">Drop a .NET .resx file in below, pick a target language, download the translated file. The .resx file stays on your device.<\/p>\n<div class=\"dft-mount dft-app\" data-format=\"resx\"><noscript><p class=\"df-noscript-message\">This translator requires JavaScript in your browser.<\/p><\/noscript><section class=\"dft-step dft-step-file dft-skeleton\" data-state=\"active\" aria-hidden=\"true\"><header class=\"dft-step-header\"><span class=\"dft-step-number\">1<\/span><h2 class=\"dft-step-title\">Add your RESX file<\/h2><span class=\"dft-step-hint\">or paste anywhere<\/span><\/header><div class=\"dft-dropzone-wrap\"><div class=\"dft-dropzone\"><div class=\"dft-dropzone-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" width=\"48\" height=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"\/><path d=\"M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2z\"\/><path d=\"M12 11v6\"\/><path d=\"M9 14l3-3 3 3\"\/><\/svg><\/div><p class=\"dft-dropzone-primary\">Drop a RESX file anywhere, <span class=\"dft-dropzone-click\">click to choose<\/span>, or paste contents<\/p><\/div><p class=\"dft-dropzone-secondary\">RESX files only. Files stay on your device.<\/p><\/div><\/section><section class=\"dft-step dft-step-language dft-skeleton\" data-state=\"future\" aria-hidden=\"true\"><header class=\"dft-step-header\"><span class=\"dft-step-number\">2<\/span><h2 class=\"dft-step-title\">Choose target language<\/h2><\/header><div class=\"dft-language-body\"><label class=\"dft-target-label\">Translate to<\/label><select class=\"dft-target-select\" disabled aria-hidden=\"true\"><option>Select language<\/option><\/select><\/div><\/section><section class=\"dft-step dft-step-progress dft-skeleton\" data-state=\"future\" aria-hidden=\"true\"><header class=\"dft-step-header\"><span class=\"dft-step-number\">3<\/span><h2 class=\"dft-step-title\">Translating<\/h2><\/header><\/section><section class=\"dft-step dft-step-review dft-skeleton\" data-state=\"future\" aria-hidden=\"true\"><header class=\"dft-step-header\"><span class=\"dft-step-number\">4<\/span><h2 class=\"dft-step-title\">Review<\/h2><\/header><\/section><div class=\"df-loading-overlay\" role=\"status\" aria-live=\"polite\"><span class=\"df-loading-overlay-spinner\" aria-hidden=\"true\"><\/span><span class=\"df-loading-overlay-label\">Loading translator...<\/span><\/div><\/div>\n<h2>How it works<\/h2>\n<p>Drop a .resx file on the page, click to choose one, or paste the contents straight in. The parser reads the file in your browser and lists every <code>&lt;data&gt;<\/code> entry whose value is a string. Pick a target language and translation starts immediately. The translated file is reassembled from the same parsed tree so the schema preamble, every <code>&lt;resheader&gt;<\/code>, every <code>&lt;metadata&gt;<\/code> block, and any typed data entries survive the round trip.<\/p>\n<h2>Quality Warning<\/h2>\n<p>Please don&#8217;t rely on the quality of these translations to ship a finalized product. This is just a starting point. It&#8217;s machine translation and there are no guarantees about its quality.<\/p>\n<h2>What we do not do<\/h2>\n<p>The file itself never leaves your device. We do not see what you are translating, we do not store any of the strings, and there is nothing about your file in our logs. The privacy wedge in DropFormat is structural: the .resx parser, the Google Translate caller, and the file writer all run inside your browser tab.<\/p>\n<p>What does leave your device: the individual strings go to <code>translate.googleapis.com<\/code> the same way they would if you pasted them into translate.google.com yourself. We are not in the middle. If your .resx file contains internal product strings you do not want a third party to see, do not translate it here; use an offline tool.<\/p>\n<h2>What it supports<\/h2>\n<p>.resx 1.x and 2.x. The parser is hand-written for the .resx subset Visual Studio writes, so it is tolerant of common real-world variations: BOM-prefixed files, Windows line endings, the embedded XSD schema Visual Studio drops in at the top of every new file, mixed quote styles on attributes, CDATA-wrapped values, and missing or out-of-order <code>resheader<\/code> entries.<\/p>\n<p><strong>String entries.<\/strong> A <code>&lt;data name=\"...\"&gt;&lt;value&gt;...&lt;\/value&gt;&lt;\/data&gt;<\/code> block whose <code>type<\/code> and <code>mimetype<\/code> attributes are absent is a translatable string. The <code>name<\/code> attribute is the stable identity .NET uses to look the string up at runtime, so DropFormat keys each entry by name and never reorders them.<\/p>\n<p><strong>Typed and binary data.<\/strong> Entries with a <code>type<\/code> attribute (e.g. <code>System.Drawing.Bitmap, System.Drawing<\/code>) or a <code>mimetype<\/code> attribute (e.g. <code>application\/x-microsoft.net.object.binary.base64<\/code>) hold serialized objects, icons, fonts, or other binary blobs. These round-trip untouched. DropFormat does not modify them and never attempts to translate them.<\/p>\n<p><strong>resheader entries are preserved.<\/strong> The four <code>&lt;resheader&gt;<\/code> entries Visual Studio writes (<code>resmimetype<\/code>, <code>version<\/code>, <code>reader<\/code>, <code>writer<\/code>) carry metadata the .NET <code>ResXResourceReader<\/code> uses at runtime. They round-trip untouched. If the mimetype or version is not the standard <code>text\/microsoft-resx<\/code> \/ <code>2.0<\/code> pair, the load banner mentions it so you can spot a file that came from an unusual toolchain.<\/p>\n<p><strong>metadata entries are preserved.<\/strong> <code>&lt;metadata&gt;<\/code> blocks hold Windows Forms designer state (anchor points, fonts, positions, splitter widths). They never contain user-facing text, so they round-trip untouched.<\/p>\n<p><strong>Comments are kept.<\/strong> The optional <code>&lt;comment&gt;<\/code> child of a <code>&lt;data&gt;<\/code> entry is the place developers leave translator-facing context (&#8220;This is the title bar text&#8221; \/ &#8220;Keep under 30 characters&#8221;). DropFormat shows the comment in the review pane and writes it back into the translated file unchanged.<\/p>\n<p><strong>xml:space=&#8221;preserve&#8221; is honored.<\/strong> Visual Studio writes <code>xml:space=\"preserve\"<\/code> on every <code>&lt;data&gt;<\/code> entry so leading and trailing whitespace in <code>&lt;value&gt;<\/code> survives the round trip. DropFormat preserves the attribute on entries that already declare it; the translated text&#8217;s whitespace is preserved verbatim regardless.<\/p>\n<p>Not yet: .NET composite-format detection (<code>{0}<\/code>, <code>{1:N2}<\/code> placeholders are passed through to the translator as part of the source text), validation that the <code>type<\/code> attribute names a real .NET type, automatic generation of culture-specific filenames (you download <code>Foo.translated.resx<\/code> and rename it to <code>Foo.de.resx<\/code> yourself), and binary <code>.resources<\/code> compilation (Visual Studio&#8217;s MSBuild step does this; the .resx file you download here drops straight back into the project).<\/p>\n<p><!-- TOLERANCES:START --><\/p>\n<h2>What we tolerate, and what we reject<\/h2>\n<p>Some malformed files we repair on the way in. Others we refuse to load so we do not make things worse. This list is the parser&#8217;s actual behaviour, generated from the format module itself, not aspirational copy.<\/p>\n<p><strong>Repaired automatically:<\/strong><\/p>\n<ul class=\"dft-tolerance-list dft-tolerance-repairs\">\n<li data-tolerance-id=\"bom-stripped\">UTF-8 byte order mark (BOM) at the start of the file<\/li>\n<li data-tolerance-id=\"crlf-normalized\">Windows (CRLF) or mixed line endings<\/li>\n<li data-tolerance-id=\"leading-blank-lines\">Leading blank lines before the XML declaration<\/li>\n<li data-tolerance-id=\"multiple-roots\">Multiple &lt;root&gt; elements (we use the first)<\/li>\n<li data-tolerance-id=\"whitespace-formatting\">Indented or whitespace-heavy XML formatting<\/li>\n<li data-tolerance-id=\"xml-comments\">XML comments anywhere in the document<\/li>\n<\/ul>\n<p><strong>Refused with an explanation:<\/strong><\/p>\n<ul class=\"dft-tolerance-list dft-tolerance-rejects\">\n<li data-tolerance-id=\"RESX_EMPTY\"><strong>Empty or whitespace-only file.<\/strong> Add at least one &lt;data name=&quot;&#8230;&quot;&gt;&lt;value&gt;&#8230;&lt;\/value&gt;&lt;\/data&gt; and re-upload.<\/li>\n<li data-tolerance-id=\"RESX_DTD\"><strong>Custom DOCTYPE or DTD declaration present.<\/strong> Remove the &lt;!DOCTYPE &#8230;&gt; line (we accept only the standard .resx shape) and re-upload.<\/li>\n<li data-tolerance-id=\"RESX_PARSE\"><strong>XML syntax error or truncated document (e.g. unclosed &lt;value&gt;).<\/strong> Fix the XML so it parses, then re-upload.<\/li>\n<li data-tolerance-id=\"RESX_NO_ENTRIES\"><strong>No translatable &lt;data&gt; entries with non-empty &lt;value&gt;.<\/strong> Confirm at least one &lt;data&gt; element has a non-empty &lt;value&gt;.<\/li>\n<li data-tolerance-id=\"RESX_NOT_UTF8\"><strong>Non-UTF-8 encoding declared.<\/strong> Re-save the file as UTF-8 and re-upload.<\/li>\n<li data-tolerance-id=\"RESX_NOT_RESX\"><strong>Looks like a different format (JSON, PO, XLIFF).<\/strong> Use the \/translate\/ hub to pick the right translator.<\/li>\n<\/ul>\n<p><!-- TOLERANCES:END --><\/p>\n<h2>Common questions<\/h2>\n<p><strong>What is a .resx file?<\/strong> .resx is the XML resource file format Visual Studio and the .NET SDK use to carry user-facing strings (and the occasional binary blob) for Windows applications. WinForms, WPF, ASP.NET, and .NET MAUI projects all read .resx files at compile time, generate strongly-typed accessor classes, and pack the result into a binary <code>.resources<\/code> file that ships with the app. Localized versions sit alongside the neutral file with a culture suffix (<code>Strings.de.resx<\/code>, <code>Strings.fr.resx<\/code>, <code>Strings.zh-Hans.resx<\/code>).<\/p>\n<p><strong>Which file should I drop here?<\/strong> The neutral file (e.g. <code>Strings.resx<\/code>) if you want to translate it into a new culture, or an existing localized file (e.g. <code>Strings.de.resx<\/code>) if you want to re-translate it from German into another language. .resx files are per-culture: one file targets one culture, so you pick the target language explicitly even if the file already declares one.<\/p>\n<p><strong>Why is the file declaring a mimetype I have never seen?<\/strong> The <code>resmimetype<\/code> <code>resheader<\/code> declares <code>text\/microsoft-resx<\/code> on every file the .NET toolchain produces. It identifies the format to <code>ResXResourceReader<\/code> at runtime; the value is fixed and never carries user text. DropFormat leaves it alone.<\/p>\n<p><strong>What happens to my embedded icons and serialized objects?<\/strong> Nothing. Entries whose <code>type<\/code> attribute names a .NET type or whose <code>mimetype<\/code> attribute names a binary content type are non-translatable and round-trip untouched. DropFormat never decodes them and never sends them to the translator endpoint.<\/p>\n<p><strong>Does the file declare a culture I should worry about?<\/strong> .resx files do not declare a culture inside the XML; the culture is encoded in the filename instead (<code>Strings.fr.resx<\/code> targets French). Pick whichever target language you want and rename the file appropriately when you save it.<\/p>\n<p><strong>Why is the translation in some cases worse than the Google Translate website?<\/strong> The free endpoint we use is the same one the Google Translate website uses, but the API does not always know about the context the website&#8217;s interface provides. For names, branded terms, or jargon, expect to override in the review pane.<\/p>\n<p><strong>What if I am translating something Google&#8217;s endpoint will not accept?<\/strong> The free endpoint occasionally returns the source unchanged for content it would rather not translate. Those entries show &#8220;kept original&#8221; in the review pane so you can hand-translate just those.<\/p>\n<p><strong>Does it cache anything?<\/strong> No. Each run starts fresh.<\/p>\n<p><strong>What about .NET composite-format placeholders like {0} or {1:N2}?<\/strong> They pass through to the translator as part of the source text. Google Translate usually leaves <code>{0}<\/code> \/ <code>{1}<\/code> \/ etc. intact, but always spot-check the output before shipping.<\/p>\n<p><strong>What about PO, XLIFF, TMX, Qt .ts, ARB, .xcstrings, .properties, JSON, .strings, Fluent?<\/strong> Each has its own translator at <code>\/translate\/po\/<\/code>, <code>\/translate\/xliff\/<\/code>, <code>\/translate\/xliff2\/<\/code>, <code>\/translate\/tmx\/<\/code>, <code>\/translate\/ts\/<\/code>, <code>\/translate\/arb\/<\/code>, <code>\/translate\/xcstrings\/<\/code>, <code>\/translate\/properties\/<\/code>, <code>\/translate\/json\/<\/code>, <code>\/translate\/strings\/<\/code>, and <code>\/translate\/fluent\/<\/code>. Drop your file at the page that matches it.<\/p>\n<h2>Why this exists<\/h2>\n<p>Visual Studio&#8217;s ResX Editor does not ship with a machine translation feature, and the third-party plugins that do exist mostly require pasting a paid translation API key into the IDE and trusting the plugin to send your strings to whoever the key belongs to. DropFormat sits in between: free, browser-based, no upload, designed for the &#8220;I just added a feature; give me a first-pass target draft I can paste back into the project and clean up&#8221; workflow.<\/p>\n<h2>What is a .resx file?<\/h2>\n<p>.resx (Resource XML) is the file format Visual Studio writes when you add a resource file to a .NET project. The file is XML with a fixed shape: an <code>&lt;xsd:schema&gt;<\/code> preamble documenting the structure, a sequence of <code>&lt;resheader&gt;<\/code> entries declaring the mimetype \/ version \/ reader \/ writer types, and any number of <code>&lt;data name=\"...\"&gt;<\/code> entries holding the actual resources. At build time, MSBuild reads the .resx file, generates a strongly-typed accessor class (<code>Strings.Designer.cs<\/code>) so the application code can write <code>Strings.WelcomeMessage<\/code> instead of looking the value up by name, and compiles the file down to a binary <code>.resources<\/code> file embedded in the assembly. At runtime, the .NET ResourceManager loads the .resources file that matches the current culture, falling back to the neutral file when a culture-specific version is absent. DropFormat operates on the .resx source-of-truth file, the same one Visual Studio reads and writes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Drop a .NET .resx file in below, pick a target language, download the translated file. The .resx file stays on your device. How it works Drop a .resx file on the page, click to choose one, or paste the contents straight in. The parser reads the file in your browser and lists every &lt;data&gt; entry [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"parent":274,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-295","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/pages\/295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/types\/page"}],"replies":[{"embeddable":true,"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/comments?post=295"}],"version-history":[{"count":1,"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/pages\/295\/revisions"}],"predecessor-version":[{"id":309,"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/pages\/295\/revisions\/309"}],"up":[{"embeddable":true,"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/pages\/274"}],"wp:attachment":[{"href":"https:\/\/www.forethought-studio.com\/convert\/wp-json\/wp\/v2\/media?parent=295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}