{"id":15098,"date":"2021-12-14T12:00:57","date_gmt":"2021-12-14T10:00:57","guid":{"rendered":"http:\/\/phraseapp.com\/blog\/?p=253"},"modified":"2023-11-02T10:30:53","modified_gmt":"2023-11-02T09:30:53","slug":"10-common-mistakes-in-software-localization","status":"publish","type":"post","link":"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/","title":{"rendered":"Localization Best Practices: How to Avoid the 10 Most Common Pitfalls"},"content":{"rendered":"<p>You\u2019re ready to release your software and show it to the world: The code seems bug-free, and the design is crisp\u2014but does it work in languages other than English?<br \/>\nIf your answer isn\u2019t affirmative, you might find yourself reworking the whole app to support other languages because you missed writing the code in a way that would allow your software product to be adapted for international markets.<br \/>\n<a href=\"https:\/\/phrase.com\/blog\/posts\/how-important-is-localization-for-your-business\/\">Localization<\/a>\u00a0is more than just about the mere translation of words from one language into another\u2014it&#8217;s about cultural awareness and adapting your software to the preferences, habits, and expectations of your target users.<br \/>\nIf you don\u2019t want to spend months fixing localization bugs, make sure you consider these 10 common pitfalls preventing apps from being properly localized for global markets\u2014and what we suggest doing instead.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_69_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Overview<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#embedding-text-directly-into-the-code-of-your-software\" title=\"Embedding text directly into the code of your software\">Embedding text directly into the code of your software<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#use-separate-resource-files\" title=\"Use separate resource files\">Use separate resource files<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#not-accounting-for-varying-language-lengths\" title=\"Not accounting for varying language lengths\">Not accounting for varying language lengths<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#design-for-50-and-give-strings-room-to-grow-and-shrink\" title=\"Design for +50% and give strings room to grow and shrink\">Design for +50% and give strings room to grow and shrink<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#specifying-a-language-but-not-a-country\" title=\"Specifying a language but not a country\">Specifying a language but not a country<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#always-use-a-full-locale\" title=\"Always use a full locale\">Always use a full locale<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#concatenating-strings\" title=\"Concatenating strings\">Concatenating strings<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#dont-assume-grammar-structures-and-be-careful-with-granularity-in-conditional-text\" title=\"Don\u2019t assume grammar structures and be careful with granularity in conditional text\">Don\u2019t assume grammar structures and be careful with granularity in conditional text<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#not-supporting-unicode\" title=\"Not supporting Unicode\">Not supporting Unicode<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#always-use-utf-8\" title=\"Always use UTF-8\">Always use UTF-8<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#hard-coding-numbers-units-dates-and-times\" title=\"Hard-coding numbers, units, dates, and times\">Hard-coding numbers, units, dates, and times<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#use-a-library-to-support-different-locales\" title=\"Use a library to support different locales\">Use a library to support different locales<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#not-considering-vertical-writing-and-right-to-left-languages\" title=\"Not considering vertical writing and right-to-left languages\">Not considering vertical writing and right-to-left languages<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#prepare-for-a-complex-text-flow\" title=\"Prepare for a complex text flow\">Prepare for a complex text flow<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#creating-ambiguity-due-to-lack-of-context\" title=\"Creating ambiguity due to lack of context\">Creating ambiguity due to lack of context<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#provide-localization-notes-and-use-code-comments\" title=\"Provide localization notes and use code comments\">Provide localization notes and use code comments<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#using-images-that-contain-text\" title=\"Using images that contain text\">Using images that contain text<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#separate-text-from-graphics\" title=\"Separate text from graphics\">Separate text from graphics<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#not-worrying-about-localization-until-its-too-late\" title=\"Not worrying about localization until it\u2019s too late\">Not worrying about localization until it\u2019s too late<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/phrase.com\/blog\/posts\/10-common-mistakes-in-software-localization\/#test-localizability-early-and-often\" title=\"Test localizability early and often\">Test localizability early and often<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2 id=\"embedding-text-directly-to-the-code\" style=\"text-align: left;\"><span class=\"ez-toc-section\" id=\"embedding-text-directly-into-the-code-of-your-software\"><\/span>Embedding text directly into the code of your software<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Embedding text directly into the code can slow down the localization process tremendously, as the translator needs to actually read the code to determine which segments need translation and which ones don\u2019t. It also makes localization more costly than necessary, and the consistency of the translation will be difficult\u2014if not impossible\u2014to maintain.<br \/>\nFiles containing hard-coded localizable content are also difficult to version control and maintain, so make sure to keep all your text in external files.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"use-separate-resource-files\"><\/span>Use separate resource files<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Translatable strings include titles, product names, error messages, and any other text that users might see when using your app\/software. You should get all of these user-facing strings out of your code and place them into resource files, giving each string a unique name (think of it as an identifier or a key).<br \/>\nThese resource files will be loaded by a library that uses a combination of language and country (also known as the \u201clocale\u201d) to identify the right string.<br \/>\nOnce you\u2019ve placed your strings in external resource files, you can send these files to your translation vendor and get back translated files for each locale that your application is going to support.<br \/>\nBe careful when choosing key IDs for your strings: The IDs should always describe the string\u2019s role in the interface (title, button label, etc.). You should also make sure that you aren\u2019t duplicating an existing ID when adding new strings.<br \/>\nThere are various file formats that make suitable resource files. Popular choices are JSON, XML, gettext, or YAML. Depending on the programming language or framework you are using, there will usually be a de-facto standard format.<br \/>\nIn Python, the GNU gettext system is quite a popular choice. A .po resource file containing the translatable strings is created for each locale:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># .\/locales\/en_US\/LC_MESSAGES\/messages.po\nmsgid \"button_order\"\nmsgstr \"Order Now\"\nmsgid \"login_message\"\nmsgstr \"Welcome back!\"<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># .\/locales\/de_DE\/LC_MESSAGES\/messages.po\nmsgid \"button_order\"\nmsgstr \"Jetzt bestellen\"\nmsgid \"login_message\"\nmsgstr \"Willkommen zur\u00fcck!\"\"<\/pre>\n<p style=\"text-align: left;\">And the gettext function is used to get the appropriate translation:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import gettext\nde_DE = gettext.translation('messages', localedir='locales', languages=['de_DE'])\nde_DE.install()\nprint(gettext(\"login_message\"))\n# Willkommen zur\u00fcck!\nprint(gettext(\"button_order\"))\n# Jetzt bestellen]<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"not-accounting-for-varying-language-lengths\"><\/span>Not accounting for varying language lengths<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Don\u2019t assume every language is as concise as English. English text is often very compact in comparison to other languages\u2014like German or Finnish\u2014and translations can vary considerably in length and density.<br \/>\nIf you don\u2019t prepare for this and there isn\u2019t enough space, your strings might overlap with other controls and the interface will require editing after translation.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"design-for-50-and-give-strings-room-to-grow-and-shrink\"><\/span>Design for +50% and give strings room to grow and shrink<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The size of the interface must be adjustable to accommodate the length of translations provided at runtime.<br \/>\nYou can solve this problem by leaving extra space after each label for the string to grow. However, by doing so, the labels and controls might appear pretty far apart from each other in compact languages. Some developers give their labels room to grow and shrink by aligning them to the right or by placing them above the controls.<br \/>\nYou can also use layout managers that understand how locale affects a UI and manage the pixel positioning of widgets for you at runtime, so your interface will adjust properly.<br \/>\nAnother way to solve this issue is by storing the dimensions for a label in the locale resource file.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"specifying-a-language-but-not-a-country\"><\/span>Specifying a language but not a country<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Sometimes a language differs depending on the country in which it&#8217;s spoken because different regions may speak and spell a shared language with nuanced differences (e.g., British English differs from American English). Specifying a language but not a country code can make localization difficult.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"always-use-a-full-locale\"><\/span>Always use a full locale<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Be as precise as possible, and always use a full locale property instead of just a language. Locales contain both the language and the country code where it&#8217;s spoken, such as fr-FR (French in France) or en-GB (English in Great Britain). This allows your app to support alternate spellings, date formats, and other differences between two countries with a shared language.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># .\/locales\/en_US\/LC_MESSAGES\/messages.po\nmsgid \"login_message\"\nmsgstr \"Hi there!\"<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># .\/locales\/en_AU\/LC_MESSAGES\/messages.po\nmsgid \"login_message\"\nmsgstr \"G'Day Mate!\"<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"concatenating-strings\"><\/span>Concatenating strings<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Some developers love to create concatenated pieces of sentences using placeholders, where the order of words and phrases is hard-coded.<br \/>\nSplitting sentences into several keys presumes grammar rules and a certain sentence structure. If you use conditional statements and conditionalize single terms or a portion of a sentence, the granularity of conditional text might cause confusion during the translation process.<br \/>\nIn this (intentionally bad) example, the structure is fixed and the sentence is broken up into tiny strings:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">msgid \"welcome_back_msg_start\"\nmsgstr \"Hey \"\nmsgid \"welcome_back_msg_end\"\nmsgstr \", welcome back!\"<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print(gettext('welcome_back_msg_start') + username + gettext('welcome_back_msg_end'))\n# Hey John, welcome back!<\/pre>\n<p>These word puzzles are very hard and sometimes almost impossible to translate, and will give translators a bitter hatred for your shenanigans, as they may only see parts of the sentence while translating and have to guess what belongs together.<br \/>\nNobody likes guessing games!<\/p>\n<h3><span class=\"ez-toc-section\" id=\"dont-assume-grammar-structures-and-be-careful-with-granularity-in-conditional-text\"><\/span>Don\u2019t assume grammar structures and be careful with granularity in conditional text<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The structure of the sentence will often be completely different in another language. Therefore, it&#8217;s best to create strings that are complete sentences.<br \/>\nTranslators must be able to control the structure of a sentence, change the order freely, and insert all kinds of prefixes, suffixes, and any other grammar elements.<br \/>\nIf a string contains a placeholder, always explain what each placeholder means and allow the translator to change the word order if necessary. Sometimes you are safer setting a condition at the sentence level.<br \/>\nConsidering the above, here is a better example. The translator can freely move the placeholder and fully control the structure of the sentence:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">msgid \"welcome_back_msg\"\nmsgstr \"Hey %(username)s, welcome back!\"<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">print(gettext('welcome_back_msg', username=\"John\"))\n# Hey John, welcome back!<\/pre>\n<h2 id=\"corrupted-characters--lack-of-unicode-support\" style=\"text-align: left;\"><span class=\"ez-toc-section\" id=\"not-supporting-unicode\"><\/span>Not supporting Unicode<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Whenever you use a wrong character encoding and your source code handles strings using a data type that cannot handle Unicode, translations will break. Programming languages often store files using the system\u2019s default encoding.<br \/>\nHowever, when your server is English and all of your users are browsing in Chinese, your characters will get corrupted.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"always-use-utf-8\"><\/span>Always use UTF-8<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Therefore, another of our localization best practices is to make sure you use UTF-8. It&#8217;s almost always the best choice as it fixes this issue by standardizing the encodings across browsers and servers.<br \/>\nSo, ideally, every layer in your stack should use UTF-8: HTML, HTTP server, database as well as the application itself. Only when you\u2019re working primarily with Asian languages, you might need UTF-16.<\/p>\n<p style=\"text-align: left;\">Specify the charset in the <code>&lt;head&gt;<\/code> of your HTML document:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&lt;meta http-equiv=\"content-type\" content=\"text\/html; charset=utf-8\"&gt;<\/pre>\n<p style=\"text-align: left;\">Verify your HTTP server is sending the correct HTTP Content-Type header:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Content-Type: text\/html; charset=utf-8<\/pre>\n<p style=\"text-align: left;\">Use UTF-8 in your database:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># MySQL\nCREATE DATABASE dbname CHARACTER SET utf8 COLLATE utf8_general_ci;\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"hard-coding-numbers-units-dates-and-times\"><\/span>Hard-coding numbers, units, dates, and times<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Hard-coded date, time, or currency formats will cause trouble during the translation process, as languages and countries differ in date and time formats. 26.04.2015 or 04.26.2014? 14:00 or 2 p.m.? 1,000 miles or 1,609 kilometers?<\/p>\n<h3><span class=\"ez-toc-section\" id=\"use-a-library-to-support-different-locales\"><\/span>Use a library to support different locales<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>As mentioned previously, <a href=\"https:\/\/phrase.com\/blog\/posts\/number-localization\/\">never hard-code numbers<\/a>, units, dates, and times, assuming that they don\u2019t need localization. Go for localizable strings instead, and let translators decide what&#8217;s best for their language.<br \/>\nYou can store all dates and times in a standard ISO format and use a library to format them for the given locale. It will also help to convert time to different time zones.<br \/>\nThe same applies to currencies and other number formats. So, always use a library with localized files for each of the locales your software needs to support.<\/p>\n<p style=\"text-align: left;\">Here\u2019s an example using Python\u2019s <a href=\"https:\/\/phrase.com\/blog\/posts\/i18n-advantages-babel-python\/\">Babel library<\/a>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">from babel.dates import format_datetime\nfrom babel.numbers import format_currency\nprint(format_datetime(locale='ru_RU'))\n# 26 \u0438\u044e\u043b\u044f 2013 \u0433., 15:48:18\nprint(format_currency(10.50, 'EUR', locale='de_DE'))\n# 10,50 \u20ac\nprint(format_currency(10.50, 'USD', locale='en_AU'))\n# US$10.50<\/pre>\n<h2 id=\"not-caring-about-vertical-writing-and-languages-that-read-right-to-left\" style=\"text-align: left;\"><span class=\"ez-toc-section\" id=\"not-considering-vertical-writing-and-right-to-left-languages\"><\/span>Not considering vertical writing and right-to-left languages<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Arabic, Hebrew, and some other languages go from right to left and East-Asian languages using Chinese\u2014or traditional Mongolian, if you feel adventurous\u2014characters have a long history of vertical writing.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"prepare-for-a-complex-text-flow\"><\/span>Prepare for a complex text flow<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Don\u2019t assume that the same rules apply to all languages and expect the need for implementing specialized versions for a complex text flow, e.g., vertical writing, and plan for languages that read right to left.<br \/>\nWhen it comes to vertical writing, strings are, for example, not rotated by 90 degrees. Instead, single characters are placed under one another.<br \/>\nYou can include a direction string in the resourced strings and use that string to load a different stylesheet based on the current locale. There\u2019s also a direction property in CSS.<br \/>\nHere&#8217;s an example:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\">h1 {\n    direction: rtl;\n}<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"css\">&lt;h1&gt;\n  Read me from right-to-left.\n&lt;\/h1&gt;<\/pre>\n<h2 id=\"confusionambiguities-due-to-lack-of-context\" style=\"text-align: left;\"><span class=\"ez-toc-section\" id=\"creating-ambiguity-due-to-lack-of-context\"><\/span>Creating ambiguity due to lack of context<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>When strings include variables, are used in a specific context, or have ambiguous wording, your translation vendor will likely have a hard time deciphering them. Translators usually work on files and strings in a context-free format. So, how will a translator know whether the single term \u201cContact\u201d is a verb for a button or a noun for a label?<\/p>\n<h3><span class=\"ez-toc-section\" id=\"provide-localization-notes-and-use-code-comments\"><\/span>Provide localization notes and use code comments<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Keep in mind to add comments and notes to the localizable files.<br \/>\nAside from glossaries and style guides, you can provide context information to translators directly in your source files. The more context you give\u2014by writing notes for translators and providing alternate phrasings\u2014the better.<br \/>\nIf you\u2019re working with content in text-based code files (XML, HTML, JSON and so on), make sure to use code comments. If you handle your translations in a spreadsheet, you can easily add a column for context notes. For an even better understanding, provide screenshots.<br \/>\nRemember that context is king when it comes to software translation and localization\u2014the more context, the better!<\/p>\n<h2><span class=\"ez-toc-section\" id=\"using-images-that-contain-text\"><\/span>Using images that contain text<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Images are a great way to save localization costs as they cut down the word count for translation and may even make your product easier to understand\u2014not to mention they are visually more appealing to the reader.<br \/>\nHowever, sometimes images that contain text can be a serious pain for translators and can slow down and otherwise hinder the translation process. In some cases, it could even result in you paying more money.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"separate-text-from-graphics\"><\/span>Separate text from graphics<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If a text needs to be associated with a graphic, try to separate your text from the image and create the text as a separate component.<br \/>\nIf the text is separable, managing localized versions becomes a lot simpler.<br \/>\nIdeally, images should not contain text at all, because it eliminates the need to translate it. Pay attention to cross-cultural differences too, as not all images and symbols carry the same meaning across borders.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"not-worrying-about-localization-until-its-too-late\"><\/span>Not worrying about localization until it\u2019s too late<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Small mistakes can prevent your software from working in other languages. Errors in source content can be replicated, or worse, amplified in various language versions, and this can derive in months of work fixing localization bugs.<br \/>\nDon\u2019t let this happen to you!<\/p>\n<h3><span class=\"ez-toc-section\" id=\"test-localizability-early-and-often\"><\/span>Test localizability early and often<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>You can save yourself a lot of trouble in the long run when you start<a href=\"https:\/\/phrase.com\/blog\/posts\/why-you-should-give-localization-testing-top-priority\/\"> testing for localization<\/a> early and often.<br \/>\nAs a developer, you can use automated tests of test translation files and character encoding for the localized version of your software.<br \/>\nAlways test your patches not just for code errors but also check strings for grammar errors, capitalization. inconsistencies, and localizability issues.<br \/>\nHaving localization in mind when creating the original software appeases the localization process a lot. If you avoid these 10 common pitfalls and diligently follow proven localization best practices, your software should be fully localizable and open up to the global market.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Save yourself the trouble with this ultimate list of best practices and avoid the most common localization mistakes from the get-go.<\/p>\n","protected":false},"author":6,"featured_media":2612,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_stopmodifiedupdate":false,"_modified_date":"","_searchwp_excluded":"","footnotes":""},"categories":[40],"class_list":["post-15098","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-localization"],"acf":[],"_links":{"self":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/15098"}],"collection":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/comments?post=15098"}],"version-history":[{"count":10,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/15098\/revisions"}],"predecessor-version":[{"id":68937,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/15098\/revisions\/68937"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/media\/2612"}],"wp:attachment":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/media?parent=15098"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/categories?post=15098"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}