diff --git a/docs/fundamentals/localization.md b/docs/fundamentals/localization.md index 36f5f34784..03a2e57f38 100644 --- a/docs/fundamentals/localization.md +++ b/docs/fundamentals/localization.md @@ -1,9 +1,487 @@ + + # Localization -Localization or internationalization (i18n) is the process of designing and preparing your app to be usable in different locales around the world. -Localization includes the support for different languages as well as different formats for entities like dates, time, decimals, currency, etc. +Internationalization is the process of designing and developing a product for localization into specific languages and regions. + +## Introduction --- + +### Internationalization (i18n) + +Internationalization (sometimes abbreviated as i18n) is the entire process of designing and developing a product that can be adapted to different languages and regions. +It is the foundation for high-quality and efficient [localization](#localization-l10n). + +### Localization (l10n) + +Localization (sometimes abbreviated as l10n) is the process of adapting a product to the language and cultural norms of a specific target market so that it feels natural to local users. This goes beyond [simple translation](#translation) and includes script direction ([LTR](#ltr-left-to-right)/[RTL](#rtl-right-to-left)), formatting numbers, times, dates, and addresses, and adapting illustrations. +Localization requires an [internationalized](#internationalization-i18n) product and must be performed for each target market. + +#### Localization example + +This example shows how values, dates, and times should be displayed after the product has been localized. + + +### Translation + +Translation is the central linguistic component of [localization](#localization-l10n), whereby the tone must be adapted to local requirements and the meaning must be conveyed accurately. +It is important for UX writers to consider that languages differ not only in terms of word order, plural rules, and punctuation, but an English word can have multiple meanings and be translated into other languages using completely different words. +In addition, an English word can have multiple meanings and be translated into other languages using different words. + +### LTR (Left-to-Right) + +LTR refers to languages (e.g., English, German, French, Spanish) and scripts that are written and read from left to right. + +### RTL (Right-to-Left) + +RTL refers to languages (e.g., Arabic, Hebrew, Persian) and writing systems that are written and read from right to left. + +Because of these differences, it's important for UX writers to consider that often the entire user interface must be mirrored, which imposes significant demands on [internationalization](#internationalization-i18n). + +## UX Writing --- + +UX writers are the text experts in the product development team and therefore ideal ambassadors for internationalization. +They need to be aware of the challenges of localization and understand how they can support UX designers in creating localization-friendly designs (e.g., [space for translation](#manage-space-for-translations)). +This page gives recommendations on how UX writers can support localization teams and translators to minimize internationalization challenges. + +### Consider translation + +Translation-friendly texts should be created by UX writers thinking like a translator and asking the question: “Is the text understandable without the visual context?”. +In the example below, UX writers should ask themselves whether a tool instance is being deleted or whether something is being named. +It is also unclear whether “complete” is an adjective or a verb. + +
+
+ +- `Delete the template for tool instance IDs` + +
+
+ +- `Delete complete tool instance ID naming` + +
+
+ +User interface texts are stand-alone, short, and to the point, but they provide little to no context on their own. Thus, translators and AI can only produce a reliable translation if the terms are + +- [Predominant](#terms-in-various-uses) +- [Precise](#use-domain-terminology) +- [Unambiguous](#avoid-misunderstandings) + + + +### Handover UX writing specifications + +The handover documentation to development must include the UX writing specifications (e.g., [placeholder names](#define-named-placeholders) or [grouping of texts](#grouping-of-texts)) as a basis for [implementing internationalization](#code). + + + +### Use domain terminology + +- The terms are defined by experts (physicists, engineers, lawyers, etc.) from universities and various global companies specializing in specific domains. +- Standardization bodies (e.g., [ISO](https://iso.org), [EN](https://cen.eu), [UL](https://ul.com), [IEC](https://iec.ch)) are the people responsible for standardizing common terms. +- UX writers should avoid terms from quasi-industrial standards until they have been harmonized with official standardization bodies and are generally accepted. + +Common language serves multiple purposes: + +- Clarity of communication, common understanding between people and companies +- Applicability across multiple systems/tools/hardware, etc. +- Openness to third parties, breaking up of silos +- Foundation for artificial intelligence + +#### Consider that terms are used in different ways + +Many terms have various meanings related to a specific context or domain. +Use the terminology database of domain to maintain a common language. +UX writers should request terms from the terminology maintainers of the domain if the term is not yet defined (via terminology databases if available). +Then UX writers should review the UI texts together with domain experts, and ensure that translations are done by translators with domain knowledge. + +!!! info "Meaning of the term `title`" + + A subset of meanings of `title`: + + - predominant meaning: an appellation of dignity, honor, distinction, or preeminence attached to a person or family by virtue of rank, office, precedent, privilege, attainment, or lands + - descriptive name : [appellation](https://www.merriam-webster.com/dictionary/appellation) + - a person holding a title especially of nobility + - a similar distinguishing name of a musical composition or a work of art + - all the elements constituting legal ownership + - a descriptive or general heading (as of a chapter in a book) + + See [Merriam Webster](https://www.merriam-webster.com/dictionary/title) for details + +One meaning always dominates regardless of context. That is the meaning that can be used without creating confusion. However, if this dominating meaning does not fit the context, an alternative term (unambiguous synonym) must be used to eliminate misunderstandings. + +
+
+ +- Academic title +- Heading +- Name +- Ownership + +
+
+ +- Title (professor, doctor xyz) +- Title of a book (War and peace) +- Title of an object (Intelligent Valve) +- Title to an asset (Owned by Mr./Ms. xyz) + +
+
+ +In addition, the alternative term substantially increases the probability of correct interpretation by artificial intelligence (as part of translation, machine learning, or any other use). + +### Avoid misunderstandings + +Avoid possible causes of misunderstandings by + +- grouping the texts by use cases +- only using the [predominant meaning](#terms-in-various-uses) of the term +- annotating texts with a description (if supported by translation framework and file format) + +#### Group texts + +Translators translate texts individually. +In order to understand the context and maintain consistency, it is necessary to have related texts close together. +Related texts can be brought together by grouping texts based on use cases (e.g., My account → Theme selection) along with meaningful (key) names. + +
+
+ +- `ACCOUNT.LOGOUT.CANCEL:` Cancel +- `ACCOUNT.LOGOUT.HEADING:` Log out +- `ACCOUNT.LOGOUT.LOG_OUT_NOW:` Log out now? +- `ACCOUNT.LOGOUT.LOGGING_OUT:` Logging out… +- `ACCOUNT.SETTINGS.HEADING:` Settings +- `ACCOUNT.SETTINGS.THEME:` Theme +- `ACCOUNT.SETTINGS.THEME_OPTIONS.AUTO:` Auto +- `ACCOUNT.SETTINGS.THEME_OPTIONS.DARK:` Dark +- `ACCOUNT.SETTINGS.THEME_OPTIONS.LIGHT:` Light +- `LEGAL.ABOUT:` About +- `LEGAL.IMPRINT:` Corporate Information +- `LEGAL.PRIVACY_POLICY:` Privacy Notice +- `LEGAL.VERSION:` Version `{{version}}` + +
+
+ +- `ABOUT:` About +- `AUTO:` Auto +- `CANCEL:` Cancel +- `DARK:` Dark +- `IMPRINT:` Corporate Information +- `LIGHT:` Light +- `LOG_OUT_NOW:` Log out now? +- `LOGGING_OUT:` Logging out… +- `LOGOUT:` Log out +- `PRIVACY_POLICY:` Privacy Notice +- `SETTINGS:` Settings +- `THEME:` Theme +- `VERSION:` Version `{{version}}` + +
+
+ +### Manage space for translations + +Design user interfaces by following these steps to ensure that translations have space in the user interface. + +1. Design UI by prioritizing flexible layouts, identify areas with limited text space, and always allocate more space than you think you'll need. +1. Write English texts, keeping conciseness in mind from the start. +1. Determine reasonable limits and provide it to the translation management. +1. Request translations +1. Test every screen with translated texts + Revisit the UI design or the original texts if a translator cannot convey the meaning within the limit. + +Fixing UI issues caused by long translations late in the development cycle is expensive and time-consuming. + +#### Be aware of length increase + +Always design with translation in mind, assuming text will grow. + +- Layout breakage + Fixed-width elements may not accommodate longer text, which can result in overflows, line breaks in awkward places, or text disappearing completely. +- Truncation + If text is truncated, important instructions or information may be invisible, which can lead to frustration and misuse. +- UI inconsistency + Different languages require different amounts of space, which makes it difficult to maintain a consistent look and feel. + +Keeping these differences in length for translations in mind supports the whole design team to create localization-friendly designs. + +#### Make space for translation + +The exact length of a translation cannot be predicted. +Some generally accepted rules of thumb: + +- Short texts (1-10 characters) + These can often increase by 200-300%. (E.g., `EN:`"On" → `DE:`"Eingeschaltet") +- Medium texts (11-20 characters) + Expect an increase of 100-200%. (E.g., `EN:`"Withdraw request" → `DE:`"Anfrage zurückziehen") +- Longer texts (21-50 characters) + Expect an increase of 50-100%. +- Very Long texts (50+ characters) + Depending on the conciseness of the language, the paragraphs can be 30-50% longer, but sometimes also shorter than the original. + +Consider German, Finnish, Greek, and some Slavic languages, which are known for their long translations. + +#### Limit space if required + +Identify UI elements which truly offer limited space, even if a flexible design is the preferred choice. +The following UI elements may require text length restrictions, measured in either character count or pixel width: + +- Buttons +- Tab labels +- Navigation menu items +- Table headers +- Input field labels + +### Reuse texts + +Before writing a new text, check whether one with the exact same meaning already exists. + +
+
+ +- `COMMON.SAVE:` Save + +
+
+ +- `USERS.EDIT_USER.SAVE:` Save +- `DEVICES.EDIT_DEVICE.SAVE:` Save + +
+
-Angular supports localization as described in the [i18n](https://angular.dev/guide/i18n) guide and is supported by [pipes](https://angular.dev/guide/templates/pipes). +Reusing the same instance of text has the following advantages: + +- reduces the volume sent to translators and lowers cost. +- increases the efficiency of product development and maintenance. +- keeps translation unique in every supported language. +- helps identifying duplicated functionality. + +However, be careful when changing approved, reused texts to ensure that their meaning is preserved. + +### Consider different contexts + +An English text may require different translations in different contexts. +In such cases, a separate text must be created. +If in doubt, create a separate text for each use, even if the English text appears to be identical. + + + +
+
+ +- `COMMON.CANCEL:` "Cancel" for processes only +- Translation to German: "Abbrechen" +- Add `CONTRACT.CANCEL:` "Cancel" for contracts +- Translation to German: "Stornieren" + +
+
+ +- `CANCEL:` "Cancel" in context of process and contract +- Translation to German: "Abbrechen" or "Stornieren"? + +
+
+ + + +### Use translation libraries + +Packages based on the [Unicode CLDR](https://cldr.unicode.org/) like `@angular/common` and built-in runtime objects like `Intl` provide complete and high quality translations for: + +- language and script names +- countries and regions +- currencies +- months, weekdays and time zones + +Use these sources to avoid superfluous translation efforts. + +### Avoid directional terms on UI + +Directional terms might be incorrect if the user interface is mirrored for [RTL languages](#rtl-right-to-left). +Use direction agnostic texts instead. + + + +
+
+ +- Site pane +- Vertical navigation + +
+
+ +- Right pane +- Left navigation + +
+
+ + + +### Avoid text concatenations + +Building sentences from fragments prevents correct grammar in many languages. +Keep sentences as one unit with placeholders. + + + +
+
+ +- EN: `Select site {site} of {company}?` +- DE: `Standort {site} von {company} auswählen?` + +
+
+ +- EN: `Select site ` + `{site}` + `of` + `{company}` + `?` +- DE: `Standort auswählen ` + `{site}` + `von` + `{company}` + `?` + +
+
+ + + +Note: The verb (`EN:`"select" / `DE:`"auswählen") is at the beginning of the sentence in English but at the end in German. + +### Define named placeholders + +Keep sentences understandable even with placeholders. + +
+
+ +- `Reactivating site {name} within activation period: {startDate} – {endDate}` + +
+
+ +- `Reactivating site {1} within activation period: {2} – {3}` + +
+
+ +### Avoid hard-coding formats + + + +Use locale-aware formatting (see [Code tab](#code)), and avoid creating UI text that depends on one single format. This helps users to understand times, values, etc. and strengthens their confidence in using the system. + +
+
+ +- Use the localization framework (see [Code tab](#code)) +- Use [placeholders](#define-understandable-placeholders) in text: `Saved on {date}` + +
+
+ +- `02/03/2026` (ambiguous) +- `1,234` in all languages (ambiguous, less or greater than 2?) + +
+
+ + + +### Consider pluralization rules + +Each language has its own grammatical rules that specify how texts containing numbers must be presented. +It is important to consider these different rules early in the UX writing and implementation process to ensure that the product can be localized correctly. + +!!! info "Pluralization examples" + + Pluralization of the `English` term «apple»: + + - 0: «I own no apple.» + - 1: «I own one apple.» + - n: «I own four apples.» + + Pluralization of the `Polish` term «Plik» (`English`: «file»): + + - 1 plik + - 2, 3, 4 pliki + - 5-21 plików + - 22-24 pliki + - 25-31 plików + +#### Consider different linguistic rules + +Depending on the language there might be up to 6 forms. The following language specific variability exists: + +| Forms | Grammatical rules | Languages | +| :---: | ------------------------------------------------------------------------------------------------------------------- | -------------- | +| 1 | No distinction between the singular and plural form | e.g. Japanese | +| 2 | Singular used for one only | e.g. English | +| 2 | Singular used for zero and one | e.g. French | +| 3 | Special case for zero | Latvian | +| 3 | Special cases for one and two | Gaelic (Irish) | +| 3 | Special case for numbers ending in `00` or `[2-9][0-9]` | Romanian | +| 3 | Special case for numbers ending in `1[2-9]` | Lithuanian | +| 3 | Special cases for numbers ending in `1` and `2`, `3`, `4`, except those ending in `1[1-4]` | e.g. Russian | +| 3 | Special cases for `1` and `2`, `3`, `4` | e.g. Czech | +| 3 | Special case for one and some numbers ending in `2`, `3`, or `4` | Polish | +| 4 | Special case for one and all numbers ending in `02`, `03`, or `04` | Slovenian | +| 6 | Special cases for one, two, all numbers ending in `02`, `03`, … `10`, all numbers ending in `11` … `99`, and others | Arabic | + +The [plural rules specification from the Unicode Common Locale Data Repository (CLDR)](https://cldr.unicode.org/index/cldr-spec/plural-rules) contains a detailed linguistic analysis. + +#### Use localization to handle pluralization + +Pluralization cannot be handled by product code or writing style. Use localization (e.g., ICU or framework plural rules) instead. + +
+
+ +- `Delete {count} rows?` +- `Delete {rowName}?` + +
+
+ +- `Delete {count} row(s)?` +- if (count == 1) {`1 row`} else {`{count} rows`} + +
+
+ +### Provide user-friendly language selection + +Provide each language name in the target language for the language switcher. + +
+
+ +- English +- Deutsch +- Français +- Italiano +- Ελληνικά +- 中文 + +
+
+ +- 英语 +- 德语 +- 法语 +- 意大利语 +- 希腊 +- 中文 + +
+
+ +## Code --- + +Angular supports localization as described in the [Angular Internationalization (i18n)](https://angular.dev/guide/i18n) guide and is supported by [pipes](https://angular.dev/guide/templates/pipes). Angular applies a compile time localization concept. It does not support the change of locales (language and formats) at runtime. Instead, for each locale it generates a new web application that supports exactly one locale. It replaces text in the HTML templates with the translations and sets a fixed [LOCALE_ID](https://angular.dev/guide/i18n/locale-id) which is used by the pipes. Changing locales is realized by changing the web application. @@ -20,9 +498,7 @@ the inputs changes. This means they do not re-render when the `LOCALE_ID` change We recommend to follow the same behavior as users changes to locales are seldom. As a consequence we need to reload the web application on locale changes. - - -## Locales in Element +### Locales in Element Element provides the service `SiLocaleService` to set the current locale like `en`, `fr` or a variant like `fr-CA` or `en-GB` as well as the available locales of the application. The service is @@ -70,7 +546,7 @@ export const APP_CONFIG: ApplicationConfig = { In addition, `fallbackEnabled` enables ngx-translate to use the translation from the `defaultLocale` language when a translate value is missing. -## Persisting locales using SiLocaleStore +### Persisting locales using SiLocaleStore Setting the `SiLocaleService.locale = 'fr'` changes the language and forces a reload of the browser window. The service uses the `SiLocaleStore` to persist the new locale. After reloading the application, the service uses the `SiLocaleStore` to load @@ -108,7 +584,7 @@ export const APP_CONFIG: ApplicationConfig = { You can also combine a Store that caches the last value in the localStore and loads in parallel the current value from a backend. -## Runtime locales changes using impure pipes +### Runtime locales changes using impure pipes If you need to support locale changes without reloading, we recommend to extend the Angular pipes and set the `pure` property to false. @@ -120,13 +596,13 @@ If you need to support locale changes without reloading, we recommend to extend export class DateImpurePipe extends DatePipe implements PipeTransform {} ``` -## Translation in Element +### Translation in Element Element >= v43 includes a translation abstraction layer which allows us to support multiple translation frameworks. There is no hard dependency to a specific translation library anymore. Therefore, by default, translation keys (`TranslatableString`) will no longer be translated. -### Supported Frameworks +#### Supported Frameworks If a translation framework is used, Element must be configured to use this framework as well. For module-based applications, the respective module must be imported in the root module. @@ -141,8 +617,6 @@ Supported frameworks: | `ngx-translate` | `@siemens/element-translate-ng/ngx-translate` | `SiTranslateNgxTModule` | `provideNgxTranslateForElement` | | | `@angular/localize` | `@siemens/element-translate-ng/angular-localize` | `SiTranslateNgLocalizeModule` | `provideNgLocalizeForElement` | The support is experimental. Please reach out to us via an issue, if you plan to use this in a productive app. | - - Remember, this is only the activation of the respective layer for Element, you still need to import and configure the framework in your application as you would normally do. @@ -152,13 +626,13 @@ If no framework is configured, Element will fall back to English. Support for `@ngneat/transloco` and other frameworks might be added in the future on request. -### Overriding default text keys globally +#### Overriding default text keys globally Element provides the possibility to override text keys on a global level. This can be used to change the default value of text keys that are used multiple times within an application but have most likely the same value. This is usually the case for static labels like `Close`, `Ok`, ... -All keys that can be overridden can be found [here.](https://element.siemens.io/api/element-ng/types/SiTranslatableKeys) +See [overridable strings from Element](https://element.siemens.io/api/element-ng/types/SiTranslatableKeys) for details. The overriding of text keys is available for every framework except `@angular/localize` due to technical limitations. @@ -177,7 +651,7 @@ import { provideSiTranslatableOverrides } from '@siemens/element-ng/translate'; export class AppModule {} ``` -### How it works +#### How it works Within Element, a `TranslatableString` is declared using a syntax based on `@angular/localize`: @@ -199,7 +673,7 @@ be [overridden by a global provider](#overriding-default-text-keys-globally). The `translate` pipe is needed for frameworks like `ngx-translate` where translation happens at runtime. It resolves a `TranslatableString` generated by `$localize` using an actual translation framework. -### Default text with @ngx-translate/core +#### Default text with @ngx-translate/core During application development, translations may be missing for certain translation keys, especially when adding new features or supporting additional languages. Without proper handling, missing translations can result in translation keys being displayed directly to users instead of meaningful text. @@ -232,7 +706,7 @@ export const appConfig: ApplicationConfig = { }; ``` -### Adding Cache busting feature to the translation \*.json files +#### Adding Cache busting feature to the translation \*.json files By default, the `*.json` files used for translation, are not hashed by Webpack during the build and may cause caching issues when newer versions of the applications are deployed. To counter this, we can either use the bundler to load translations @@ -261,6 +735,6 @@ Note that this hash key will only be appended to the translation based JSON file -### Translatable keys in Element +#### Translatable keys in Element