# Translations

{% hint style="info" %}
**Container Compatibility**

This feature is compatible with version 4.20 and later of the JourneyApps Container.
{% endhint %}

### Edit Translations Files

A language can be added to your app via the **Add language** action in OXIDE. This initializes a YAML file for the language, which stores the language's translation strings.

The following languages are currently supported:

* Arabic (since version 4.86.1 of the JourneyApps Runtime - see the [developer notes](#developer-notes-for-arabic) section below).
* English (US) - default
* Chinese (Simplified)
* Dutch
* French
* German
* Italian
* Japanese
* Korean
* Portuguese (Brazil)
* Russian
* Spanish (Latin America)
* Swedish

YAML files can be accessed in OXIDE via the command palette, or in the *Languages* section in the *App Tree* panel.

An example translation file is given below:

```yaml
# translations/es-419.yml
Name: Español
NameShort: Esp.
common:
months:
January: Enero
February: Febrero
March: Marzo
April: Abril
May: Mayo
June: Junio
July: Julio
August: Agosto
September: Septiembre
October: Octubre
November: Noviembre
December: Diciembre
greeting: ¡Hola {name}!
```

{% hint style="info" %}
**YAML oddities**

YAML has some standards that you might run into:

1. Words such as YES, yes, No, etc are reserved and will break your app if you use them
2. The colon (:) is a reserved symbol, so your translation needs to be surrounded by quotes if you have a colon in your string
3. Given the above, it's HIGHLY recommended that you always enclose your strings in quotes
4. Quotes themselves are reserved characters in YAML and need to be escaped using a quote. This means you may end up with a translation entry like this:

```yaml
view.path.string: 'YAML has its quirks and it''s important to be aware of them.'
```

{% endhint %}

### Call Translation Resources

Strings can be translated using the JavaScript/TypeScript `t(key, params)` function. The `t` function accepts a translation key and an optional string interpolation hash. The current locale is used to find the appropriate translation. If a translation cannot be found then `key` will be returned and a warning logged to the console.

### Translations from JavaScript

Example view XML:

{% code title="main.view\.xml" %}

```xml
<view title="JS Translations">
    <var name="name" type="text" />
    <var name="month" type="text" />
    <var name="greeting1" type="text" />
    <var name="greeting2" type="text" />

    <text-input bind="name" required="false" />
    <info>month: {month}</info>
    <info>greeting1: {greeting1}</info>
    <info>greeting2: {greeting2}</info>
    <button label="Demo Translations" on-press="$:foo()" validate="false" />
</view>
```

{% endcode %}

Example view JavaScript:

{% code title="main.js" %}

```javascript
function foo() {
    view.month = t("common.months.January");
    view.greeting1 = t("greeting", {name: "Joe"});
    view.greeting2 = t("greeting", {name: view.name});
}
```

{% endcode %}

### Translations from XML

The translation function can also be accessed from view XML.

Example view XML:

{% code title="main.view\.xml" %}

```xml
<view title="XML Translations">
    <var name="name" type="text" />

    <text-input bind="name" required="false" />
    <info>Month (XML): {$:t("common.months.February")}</info>
    <info>Greeting 1 (XML): {$:t("greeting", {name: "Joe"})}</info>
    <info>Greeting 2 (XML): {$:t("greeting", {name: view.name})}</info>
</view>
```

{% endcode %}

### Enable a language for app users

To enable a language so that it is selectable by app users, fire the **Enable language** action via the command palette or by right-clicking on the YAML file in the *App Tree* panel.

### Developer notes for Arabic

{% hint style="info" %}
**Version compatibility**

* Arabic was introduced as a supported app language in version **4.86.1** of the JourneyApps Runtime.
* For TypeScript apps the JourneyApps Runtime Build version needs to be **2.1.5** or greater. This version can be configured in your app's `package.json` file. You need to run the **Update yarn.lock** action in OXIDE after making updates to this file.
  {% endhint %}

Arabic differs from all other supported app languages in that it is displayed from right-to-left. Right-to-left language support was added to the JourneyApps Runtime in version 4.86.1 so that there is almost no additional configuration that the developer is required to implement when adding Arabic as a language.&#x20;

The Runtime automatically displays all UI components and runtime elements as right-to-left when a user selects Arabic as their language. Often this means that the specified default for an alignment or positioning attribute is different in Arabic than it is for other languages.&#x20;

As an example, let's look at the [`icon-position`](https://docs.journeyapps.com/reference/build/ui-components/xml-fields/icon-position) attribute where the default value is `left`. In Arabic, the default `icon-position` for components is `right`, since elements are read from left to right. This value can still be overwritten in Arabic as with any other language by setting/updating the attribute.

Here is a summary of updates the JourneyApps Runtime makes when a user selects Arabic as their app language:

1. The app font changes to Noto Sans if installed on the user's device
2. UI components and other runtime elements switch to right-to-left mode:
   1. Text is generally right-aligned
      1. There are some exceptions: e.g. button labels. The developer can manually right align this text if required on an app, view or component level (using [component configuration](https://docs.journeyapps.com/reference/build/app-styling-and-customizations/component-styling-and-configuration)).
   2. Icons, radio buttons, checkboxes, etc, are generally aligned to the right of text
      1. User-defined icons (e.g. `icon=“fa-arrow-right”`) are not updated by the Runtime. The developer would need to do this for directional icons - see the [section below](#user-defined-icons).
   3. An example runtime element update is the app header, which is mirrored in Arabic:

      <figure><img src="https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2FA5Z4i5lkrwB9eZ3eGjMU%2Fimage.png?alt=media&#x26;token=70d07c08-7a61-41da-bb8c-91ecc03ff1a4" alt=""><figcaption></figcaption></figure>
   4. Runtime-level directional icons are mirrored: e.g. the navigational “Back” button switches from `<` to `>`

#### User-defined directional icons

Developers will need to update user-defined directional icons when implementing Arabic, e.g:

```xml
<button label="Navigate Back" icon="fa-arrow-left" validate="false" />
```

Which looks as follows in English:

<figure><img src="https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2FVIaBTtCQwfk9zo70XoBk%2Fimage.png?alt=media&#x26;token=7d5104a2-dba8-4cbb-8ef6-97ec32aecff9" alt=""><figcaption></figcaption></figure>

Will update to the following in Arabic by the runtime (the icon position updates to the right of the text):

<figure><img src="https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2FP70CMhMtX6pL2NNbFvvS%2Fimage.png?alt=media&#x26;token=0abf35f1-f808-4171-8ef8-b5bd38a10584" alt=""><figcaption></figcaption></figure>

However, the icon itself should most likely also [be mirrored](https://material.io/design/usability/bidirectionality.html#mirroring-elements). For this developers could use `journey.locale` to dynamically update icons based on the user's language:

{% code title="main.view\.xml" %}

```xml
<button label="Navigate Back" icon="$:mirrorIcon()" validate="false" />
```

{% endcode %}

{% code title="main.js" %}

```javascript
function mirrorIcon() {
    if (journey.locale == "ar") {
        return "fa-arrow-right";
    }
    else {
        return "fa-arrow-left"
    }
}
```

{% endcode %}
