{"id":36815,"date":"2022-11-08T21:45:34","date_gmt":"2022-11-08T21:45:34","guid":{"rendered":"https:\/\/www.globalizationpartners.com\/?p=36815"},"modified":"2022-11-08T21:46:47","modified_gmt":"2022-11-08T21:46:47","slug":"best-practices-for-angular-internationalization","status":"publish","type":"post","link":"https:\/\/www.globalizationpartners.com\/2022\/11\/08\/best-practices-for-angular-internationalization\/","title":{"rendered":"Best Practices for Angular Internationalization"},"content":{"rendered":"<p>When building an application, it is not a question of if it might be used by a global audience, but a matter of when it will be offered to global markets. This is why it is important to build an application with internationalization (i18n) in mind.<\/p>\n<p>Planning to support multiple languages, not only includes the GUI (graphical user interface), but also other aspects like formatting dates and numbers, applying different currencies, and supporting language-specific fonts (including bi-directional). Depending on the framework or content management system (CMS) you are going to use to build your application, you might have different alternatives to internationalize it. In this blog, we will cover the best practices for the internationalization process of an Angular app.<\/p>\n<h2><strong>\u00a0<\/strong><\/h2>\n<h2><strong>Overview<\/strong><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-36816 alignright\" style=\"float: right; margin: 0.5em 0 0.5em 1em;\" src=\"https:\/\/www.globalizationpartners.com\/wp-content\/uploads\/2022\/11\/Best-Practices-for-Angular-Internationalization.jpg\" alt=\"Best Practices for Angular Internationalization\" width=\"475\" height=\"267\" srcset=\"https:\/\/www.globalizationpartners.com\/wp-content\/uploads\/2022\/11\/Best-Practices-for-Angular-Internationalization.jpg 650w, https:\/\/www.globalizationpartners.com\/wp-content\/uploads\/2022\/11\/Best-Practices-for-Angular-Internationalization-300x169.jpg 300w\" sizes=\"(max-width: 475px) 100vw, 475px\" \/>To internationalize your Angular app to support multiple languages; follow these steps:<\/p>\n<p>1- Install needed dependencies.<\/p>\n<p>2- Prepare project for translation.<\/p>\n<p>3- Extract text to be sent to <a href=\"https:\/\/www.globalizationpartners.com\/\">translator<\/a>.<\/p>\n<p>4 &#8211; Use .xlf file after translation and set project to localization.<\/p>\n<p>Let\u2019s start our journey.<\/p>\n<p>&nbsp;<\/p>\n<h2><strong>Install Dependencies<\/strong><\/h2>\n<p>Install a localized package to a project by using the Angular CLI and (ng add @angular\/localize) command, then we will add the @angular\/localize package, afterward, the package.json file will be updated.<\/p>\n<p>&nbsp;<\/p>\n<h2><strong>Prepare Components for Translation<\/strong><\/h2>\n<h3><strong>Prepare the Value of an Element<\/strong><\/h3>\n<p>To prepare the fixed text in the template, we will use the i18n attribute to mark all static text to be translated;<\/p>\n<p>We must place the i18n attribute on <em>every<\/em> element tag we want to translate.<\/p>\n<p>Example:<\/p>\n<p>&lt;h1 i18n&gt; Welcome in GPI! &lt;\/h1&gt;<\/p>\n<p>We added the i18n attribute in the element to mark the h1 element tag as a translatable element.<\/p>\n<p>When Angular executes the extract process, it will understand that the h1 tag is to be translated.<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Prepare the Attribute of an Element<\/strong><\/h3>\n<p>To mark the title attribute for translation, you will add i18n-title.<\/p>\n<p>Example:<\/p>\n<p>&lt;img [src]=&#8221;logo&#8221; i18n-title title=&#8221;GPI logo&#8221; alt=&#8221; GPI logo&#8221;\/&gt;<\/p>\n<p>In the previous example we used the following format to mark the \u201ctitle\u201d attribute for translation:<\/p>\n<p>i18n-{attribute_name}=&#8221;{i18n_metadata}&#8221; {attribute_name}=&#8221;{attribute_value}&#8221;<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Preparing Text in Component Code<\/strong><\/h3>\n<p>As we use a variable in the ts class, we need to also mark this text for translation, to do that we use backtick (`) characters to surround the text and metadata.<\/p>\n<p>For text only:<\/p>\n<p>$localize `string_to_translate`;<\/p>\n<p>To add i18n metadata we will surround it by (:) as shown here:<\/p>\n<p>$localize `:{i18n_metadata}:string_to_translate`<\/p>\n<p>When we need to include interpolated text, will use this format:<\/p>\n<p>$localize `string_to_translate ${variable_name}:placeholder_name:`;<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Preparing Plural Expressions<\/strong><\/h3>\n<p>The difficulty with plural expressions is that different languages have different pluralization rules. To mark plural expressions, we use the plural clause:<\/p>\n<p>{ component_property, plural, pluralization_categories },<\/p>\n<p>Notice that we will put plural in the (pluralization_categories) part:<\/p>\n<p>Example : =0 { } zero { }<\/p>\n<p>Notice this example:<\/p>\n<p>( updated x minutes ago )<\/p>\n<p>&lt;span i18n&gt;Updated X minutes ago &lt;\/span&gt;<\/p>\n<p>We can mark it as:<\/p>\n<p>&lt;span i18n&gt;Updated {minutes, plural, =0 {just now} =1 {one minute ago} other<\/p>\n<p>{{{minutes}} minutes ago}}&lt;\/span&gt;<\/p>\n<p>For more detailed information about the pluralization category, check out\u00a0 <a href=\"https:\/\/angular.io\/\">Angular<\/a> Documentation.<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Preparing Alternate Expressions<\/strong><\/h3>\n<p>We can use the (select) clause to mark choices for alternate text:<\/p>\n<p>Format: { component_property, select, selection_categories }<\/p>\n<p>We enter the text (English) surrounded by the curly brace ({}) characters after the selection category:<\/p>\n<p>&lt;span i18n&gt;The main course is {main_course, select, meat { meat } fish { fish } other {other}}&lt;\/span&gt;<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Export Content for Translation<\/strong><\/h3>\n<p>Now that we have finished preparing the components, we will extract all marked text by using Angular CLI.<\/p>\n<p>By using \u201d<a href=\"https:\/\/angular.io\/cli\/extract-i18n\">extract-i18n<\/a>\u201d command, Angular will create a source language file named \u201cmessages.xlf\u00a0\u201d\u00a0and it will be created in the root directory.<\/p>\n<p>To create the file in specific directory we can use: \u201cng extract-i18n &#8211;output-path src\/locale\u201d<\/p>\n<p>Then, create a copy of the file for each language; we rename each language file depending on the locale needed following this format:<\/p>\n<p>file_name.{locale}.xlf\u00a0 like\u00a0\u00a0 messages.fr.xlf<\/p>\n<p>it is preferred to create a directory for translation files like: src\/locale inside .xlf file, we will find the &lt;trans-unit&gt; tag for every marked text. Inside this tag there is tag &lt;source&gt;, this tag contains marked source text.<\/p>\n<p>The translator can use the xlf editor App or manually by adding a new tag named &lt;target&gt; and write the value inside.<\/p>\n<p>Simple example:<\/p>\n<p>&lt;trans-unit id=&#8221;introduction&#8221; datatype=&#8221;html&#8221;&gt;<\/p>\n<p>&lt;source&gt;Hello&lt;\/source&gt;<\/p>\n<p>&lt;target&gt;Bonjour&lt;\/target<\/p>\n<p>&lt;\/trans-unit&gt;<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Import Translated Content<\/strong><\/h3>\n<p>Now we need to prepare the app for localization by adding specific properties in angulal.json file.<\/p>\n<p>As in next snippet code, we will add the new property \u201ci18n\u201d and we will specify the source locale that is the locale used in source code.<\/p>\n<p>We will add other property \u201clocales\u201d and the specific locales that the App can support.<\/p>\n<p>Once we finish, we need to merge the translations into our application.<\/p>\n<p>Go to the angular.json file and add new settings<\/p>\n<p>&#8220;i18n&#8221;: {<\/p>\n<p>&#8220;sourceLocale&#8221;: &#8220;en-US&#8221;,<\/p>\n<p>&#8220;locales&#8221;: {<\/p>\n<p>&#8220;fr-CA&#8221;:&#8221;src\/locale\/messages.fr.xlf&#8221;,<\/p>\n<p>\/\/.. } }<\/p>\n<p>Moreover, we will add another property in this path: architect &gt; build &gt; options<\/p>\n<p>Add &#8220;localize&#8221;:\u00a0true<\/p>\n<p>Now the app is ready to build; by using Angular CLI, we will write this command \u201cng build &#8211;localize\u201d.<\/p>\n<p>For more details and in-depth understanding please check <a href=\"https:\/\/angular.io\/\">Angular<\/a> Documentation.<\/p>\n<p><strong>\u00a0<\/strong><\/p>\n<h3><strong>Format Data Based on Locale<\/strong><\/h3>\n<p>We will use the pipes that Angular provides for this purpose, notice the data transformation pipes use the <a href=\"https:\/\/angular.io\/api\/core\/LOCALE_ID\">LOCALE_ID<\/a>\u00a0token to format data based on rules of each locale.<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Currencies Formatting<\/strong><\/h3>\n<p>Using <a href=\"https:\/\/angular.io\/api\/common\/CurrencyPipe\">CurrencyPipe<\/a> transforms a number into a currency string.<\/p>\n<p><a href=\"https:\/\/angular.io\/api\/common\/CurrencyPipe\">currency<\/a>Obj: number = 0.359;<\/p>\n<p>{{<a href=\"https:\/\/angular.io\/api\/common\/CurrencyPipe\">currency<\/a>Obj | <a href=\"https:\/\/angular.io\/api\/common\/CurrencyPipe\">currency<\/a>}}\u00a0 \/\/ output &#8216;$0.36&#8217;<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Numbers Formatting<\/strong><\/h3>\n<p>Decimal Pipe transforms a number into a decimal number string.<\/p>\n<p>pi: number = 3.14159265359;<\/p>\n<p>Without specified formatting:<\/p>\n<p>{{pi | number}}\u00a0\u00a0\u00a0 output: &#8216;3.142&#8217;<\/p>\n<p>With specified formatting:<\/p>\n<p>{{pi | number:&#8217;4.1-5&#8242;}} output: &#8216;0,003.14159&#8217;<\/p>\n<p>With specified formatting and locale:<\/p>\n<p>{{pi | number:&#8217;4.1-5&#8242;:&#8217;fr&#8217;}} \u00a0output: &#8216;0\u202f003,14159&#8217;<\/p>\n<p>&nbsp;<\/p>\n<h3><strong>Numbers Dates<\/strong><\/h3>\n<p>Use DatePipe to format a date value.<\/p>\n<p>&nbsp;<\/p>\n<p>dateObj: number = Date.now();<\/p>\n<p>&nbsp;<\/p>\n<p>{{ dateObj | <a href=\"https:\/\/angular.io\/api\/common\/DatePipe\">date<\/a> }} \/\/ output is &#8216;Jun 15, 2022&#8217;<\/p>\n<p>or format like<\/p>\n<p>{{ dateObj | <a href=\"https:\/\/angular.io\/api\/common\/DatePipe\">date<\/a>:&#8217;medium&#8217; }} \/\/ output is &#8216;Jun 15, 2022, 9:43:11 PM&#8217;<\/p>\n<p>&nbsp;<\/p>\n<h4><strong>Conclusion<\/strong><\/h4>\n<p>The localization of an application is an important aspect to consider when starting the design process. By developing the application to be language-independent and able to handle the intricacies of multiple languages from inception, you will save time and money.<\/p>\n<p>With the continued growth of the global marketplace, most websites nowadays are prepared for localization. Angular makes this process easier by providing simple localization techniques, with simple steps to follow, you can get a fully localized application. Designing an application with localization in mind is the best practice to avoid a lot of complexity when localization is introduced at later stages of the project lifecycle.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When building an application, it is not a question of if it might be used by a global audience, but a matter of when it will be offered to global markets. This is why it is important to build an application with internationalization (i18n) in mind. Planning to support multiple languages, not only includes the [&hellip;]<\/p>\n","protected":false},"author":42,"featured_media":36816,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[1314,1711,1196,673,1783,1712],"_links":{"self":[{"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/posts\/36815"}],"collection":[{"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/comments?post=36815"}],"version-history":[{"count":6,"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/posts\/36815\/revisions"}],"predecessor-version":[{"id":36827,"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/posts\/36815\/revisions\/36827"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/media\/36816"}],"wp:attachment":[{"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/media?parent=36815"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/categories?post=36815"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.globalizationpartners.com\/wp-json\/wp\/v2\/tags?post=36815"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}