# Internationalization

Homey Apps can store translated strings as JSON files in the `/locales/` folder with the language code as filename. See these two example translation files for English and Dutch:

{% code title="/locales/en.json" %}

```javascript
{
  "title": "Hello World",
  "greeting": "Hello, __name__",
  "settings": {
    "title": "My Title",
    "intro": "This is an example page."
  },
  "pair": {
    "press_button": "Press the `pair` button on your device."
  }
}
```

{% endcode %}

{% code title="/locales/nl.json" %}

```javascript
{
  "title": "Hallo Wereld",
  "greeting": "Hallo, __name__",
  "settings": {
    "title": "Mijn Titel",
    "intro": "Dit is een voorbeeld pagina."
  },
  "pair": {
    "press_button": "Druk op de `pair` knop op jou apparaat."
  }
}
```

{% endcode %}

These files define translations with the ID's: `title`, `greeting`, `settings.title`, `settings.intro`, and `pair.press_button`. If a translated string with a certain ID is not present in the locale file for the users locale Homey will fall-back to English.

{% hint style="info" %}
Your app's `README.txt` can also be translated by creating additional `README.<languagecode>.txt` files. For example`README.nl.txt` would contain the Dutch translation of the readme.
{% endhint %}

## The translation object

In addition to the translation files you can define the translations directly inside the [App Manifest](https://apps.developer.homey.app/the-basics/app/manifest). This is done by defining an object with the language code as keys and the translations as the values.

```javascript
"title": {
  "en": "Hello, World!",
  "nl": "Hallo, wereld!"
}
```

You can also input a single string, when translation isn't necessary:

```javascript
"title": "°C"
```

{% hint style="info" %}
Always have at least an `en` translation! This is what Homey will fall-back on when the user language can't be found.
{% endhint %}

## Temperature conversion

Your Homey app should always use Celsius internally, Homey will automatically converts capability values from Celsius to Fahrenheit. For custom capabilities make sure the `"unit"` is set to `"°C"` to let Homey know that this value should be converted.

## Supported Languages

The following languages are currently supported for any Homey app.

* `en`: English
* `nl`: Dutch
* `de`: German
* `fr`: French
* `it`: Italian
* `sv`: Swedish
* `no`: Norwegian
* `es`: Spanish
* `da`: Danish
* `ru`: Russian
* `pl`: Polish
* `ko`: South Korean
* `ar:` Arabic

## Translating a string from your app

In your App, Drivers or Devices you can call the translation method on their Homey instance with the identifier of the translated string to get the translation. In the following example we define a translation with the ID `title` and use the translation in our `App` class.

{% code title="/locales/en.json" %}

```json
{
  "title": "Hello, World!"
}
```

{% endcode %}

{% tabs %}
{% tab title="JavaScript" %}
{% code title="/app.js" %}

```javascript
const Homey = require('homey');

class App extends Homey.App {
  onInit() {
    console.log(this.homey.__("title")); // "Hello, World!"
  }
}

module.exports = App;
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="/app.mts" %}

```mts
import Homey from 'homey';

export default class App extends Homey.App {
  async onInit(): Promise<void> {
    console.log(this.homey.__('title')); // "Hello, World!"
  }
}

```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code title="/app.py" %}

```python
from homey import app


class App(app.App):
    async def on_init(self) -> None:
        print(self.homey.translate("title"))  # "Hello, World!"


homey_export = App

```

{% endcode %}
{% endtab %}
{% endtabs %}

You can also use variables in your translations. In the translated string variables are surrounded by two underscores (`__`). To get the translated string with variables you should call the translation method with the values that you want to use for those variables.

{% code title="/locales/en.json" %}

```json
{
  "greeting": "Hello, __name__!"
}
```

{% endcode %}

{% tabs fullWidth="false" %}
{% tab title="JavaScript" %}
{% code title="/app.js" %}

```javascript
const Homey = require('homey');

class App extends Homey.App {
  onInit() {
    console.log(this.homey.__("greeting", { name: "Dave" })); // "Hello, Dave!"
  }
}

module.exports = App;
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="/app.mts" %}

```mts
import Homey from 'homey';

export default class App extends Homey.App {
  async onInit(): Promise<void> {
    console.log(this.homey.__('greeting', { name: 'Dave' })); // "Hello, Dave!"
  }
}

```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code title="/app.py" %}

```python
from homey import app


class App(app.App):
    async def on_init(self) -> None:
        print(self.homey.translate("title", name="Dave"))  # "Hello, Dave!"


homey_export = App

```

{% endcode %}
{% endtab %}
{% endtabs %}

## Translating a string in Custom views

Within your custom views, you can also use translations. For example:

{% code title="/locales/en.json" %}

```javascript
{
  "settings": {
    "title": "My Title",
    "intro": "This is an example page."
  }
}
```

{% endcode %}

{% code title="/settings/index.html" %}

```markup
<header class="homey-header">
  <h1 class="homey-title" data-i18n="settings.title">
    <!-- "My Title" will be placed here -->
  </h1>
  <p class="homey-subtitle" data-i18n="settings.intro">
    <!-- "This is an example page." will be placed here -->
  </p>
</header>
```

{% endcode %}

It is also possible to get translated strings with JavaScript:

{% code title="/settings/index.html" %}

```markup
<script type="application/javascript">
  function onHomeyReady(Homey) {
    alert(Homey.__("settings.title")); // will alert "Settings page title"
  }
</script>
```

{% endcode %}

To lean more about custom views you can read to the [custom views guide](https://apps.developer.homey.app/advanced/custom-views).

## Right-to-Left (RTL) and Arabic Language Support

Homey supports Right-to-Left (RTL) languages, including Arabic (ar). When an RTL language is active, the visual flow of the interface is mirrored, affecting layout direction, alignment, and spacing.

### **Built-in Pairing Views**

All built-in pairing views provided by the Homey App SDK fully support RTL out of the box.

If your app uses these pairing views, RTL layout behavior is handled automatically by Homey. To fully support Arabic and other RTL languages, make sure your app also includes the appropriate translations so the interface content is properly localized.

### **Custom Pairing Views**

If your app uses custom pairing views, you must ensure they work correctly in RTL layouts.

When a Right-to-Left (RTL) language is active, custom views may require adjustments to:

* layout direction
* text alignment
* margins, padding, or positioning
* icon placement and visual order

You can apply RTL-specific styling by using the CSS `:dir(rtl)` selector.&#x20;

```css
.my-custom-class {
  transform: translate(-50%);
}

.my-custom-class:dir(rtl) {
  transform: translateX(50%);
}
```

For RTL-specific styling guidance, see [HTML and CSS Styling](https://apps.developer.homey.app/advanced/custom-views/html-and-css-styling#right-to-left-rtl-styling).

## Translating with OpenAI

To translate your app automatically, Homey CLI has a built-in integration that asks OpenAI to translate all `.json` and `README.txt` files. First, create an OpenAI API Key at <https://platform.openai.com/api-keys> and connect a payment method.

Then, execute in a command line:

```bash
$ homey app translate --api-key "..."
```

{% hint style="info" %}
We found that translating an entire app usually costs less than $1.
{% endhint %}
