> For the complete documentation index, see [llms.txt](https://apps.developer.homey.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://apps.developer.homey.app/the-basics/widgets/settings.md).

# Settings

Widgets can have settings that users can change while selecting or editing a widget. This allows you to add some initial variables to your widgets.

<pre class="language-json" data-title="widget.compose.json"><code class="lang-json"><strong>{
</strong>  "name": {
    "en": "My Widget"
  },
  "settings": [
    {
      "id": "text",
      "type": "text",
      "title": {
        "en": "Text"
      },
      "hint": {
        "en": "Your number"
      }
    },
    {
      "id": "number",
      "type": "number",
      "title": {
        "en": "Number"
      },
      "hint": {
        "en": "Your number"
      }
    }
  ]
}
</code></pre>

## Defining Settings

Every setting has a `type` property that determines what values it can have and how it is presented to the user. The `value` property of each setting is the initial value of the setting. The following setting types are supported:

### Text

`string | null`

This is a single line text input whose value is a string. You can optionally validate the value using a regex pattern by adding a `pattern` property.

```json
{
  "id": "text",
  "type": "text",
  "title": { "en": "Text" },
  "value": "My initial value",
  "hint": { "en": "My text hint." },
  "pattern": "[a-zA-Z]"
}
```

### Textarea

`string | null`

This setting type allows users to input multi-line text.

```json
{
  "id": "description",
  "type": "textarea",
  "title": { "en": "Textarea" },
  "value": "Enter your description here.",
  "hint": { "en": "Provide a detailed description." },
  "pattern": "[a-zA-Z]"
}
```

### Number

`number | null`

This setting type allows users to input numerical values. The `min` and `max` properties are optional and can be used to define the acceptable range of values.

```json
{
  "id": "age",
  "type": "number",
  "title": { "en": "Age" },
  "value": 25,
  "hint": { "en": "Your age." },
  "min": 0,
  "max": 120
}
```

### Dropdown

`string | null`

This setting type allows users to select a value from a predefined list.

```json
{
  "id": "dropdown",
  "type": "dropdown",
  "title": {
    "en": "Dropdown",
    "nl": "Dropdown"
  },
  "value": "heating",
  "values": [
    {
      "id": "heating",
      "title": {
        "en": "Heating"
      }
    },
    {
      "id": "cooling",
      "title": {
        "en": "Cooling"
      }
    }
  ]
}
```

### Checkbox

`boolean | null`

This setting type allows users to enable or disable a feature.

```json
{
  "id": "checkbox",
  "type": "checkbox",
  "value": true,
  "title": {
    "en": "Checkbox",
    "nl": "Checkbox"
  }
}
```

### Autocomplete

`object | null`

This setting type provides an input that suggests options as the user types.

```json
{
  "id": "composer",
  "type": "autocomplete",
  "title": {
    "en": "Composer"
  }
}
```

{% tabs %}
{% tab title="JavaScript" %}

```javascript
'use strict';

const Homey = require('homey');

class MyApp extends Homey.App {

  async onInit() {
    const widget = this.homey.dashboards.getWidget('my-widget')

    widget.registerSettingAutocompleteListener('composer', async (query, settings) => {
      return [
        {
          name: "Mozart",
          // Optionally provide the following properties.
          description: "...",
          image: "https://some.url/",

          // You can freely add additional properties
          // that you can access in Homey.getSettings()['mySettingId'].
          id: "mozart",
        },
        {
          name: "Amadeus",

          // You can freely add additional properties
          // that you can access in Homey.getSettings()['mySettingId'].
          id: "amadeus",
        },
      ].filter((item) => item.name.toLowerCase().includes(query.toLowerCase()));
    });
  }
}

module.exports = MyApp;
```

{% endtab %}

{% tab title="TypeScript" %}

```mts
import Homey, { Widget } from "homey";

export default class App extends Homey.App {
  async onInit(): Promise<void> {
    const widget = this.homey.dashboards.getWidget("my-widget");

    widget.registerSettingAutocompleteListener(
      "composer",
      async (query: string, settings): Promise<Widget.SettingAutocompleteResults> => {
        return [
          {
            name: "Mozart",
            // Optionally provide the following properties.
            description: "...",
            image: "https://some.url/",

            // You can freely add additional properties
            // that you can access in Homey.getSettings()['mySettingId'].
            id: "mozart",
          },
          {
            name: "Amadeus",

            // You can freely add additional properties
            // that you can access in Homey.getSettings()['mySettingId'].
            id: "amadeus",
          },
        ].filter(item => item.name.toLowerCase().includes(query.toLowerCase()));
      },
    );
  }
}

```

{% endtab %}

{% tab title="Python" %}

```python
from homey import app
from homey.widget import SettingAutocompleteResult


class App(app.App):
    async def on_init(self) -> None:
        widget = self.homey.dashboards.get_widget("my-widget")

        async def autocomplete_listener(
            query, settings
        ) -> list[SettingAutocompleteResult]:
            results: list[SettingAutocompleteResult] = [
                {
                    "name": "Mozart",
                    # Optionally provide the following properties.
                    "description": "...",
                    "image": "https://some.url/",
                    "data": {
                        # You can freely add additional properties
                        # that you can access in Homey.getSettings()['mySettingId'].data
                        "id": "mozart",
                    },
                },
                {
                    "name": "Amadeus",
                    "data": {
                        # You can freely add additional properties
                        # that you can access in Homey.getSettings()['mySettingId'].data
                        "id": "amadeus",
                    },
                },
            ]

            return [
                result for result in results if query.lower() in result["name"].lower()
            ]

        widget.register_setting_autocomplete_listener("artist", autocomplete_listener)


homey_export = App

```

{% endtab %}
{% endtabs %}

## Accessing Settings

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

```html
<html>

<head>
...
</head>

<body>
  <script type="text/javascript">
    function onHomeyReady(Homey) {
      Homey.ready();
    
      for (const [settingId, settingValue] of Object.entries(Homey.getSettings())) {
        // Do something with the settings...
      }
    }
  </script>
</body>

</html>
```

{% endcode %}

## Devices

Many widgets are designed to display content based on specific Homey devices. To simplify this, a dedicated `devices` setting is provided, allowing users to select one or more devices. Once selected, your widget can access their IDs using `Homey.getDeviceIds()`.

**Configuration Options**

The `devices` setting includes the following required properties:

* **`singular` (boolean, required)** – Determines whether users can select multiple devices:
  * `false` – Allows selecting multiple devices.
  * `true` – Restricts selection to a single device.
* **`type` (string, required)** – Defines the scope of selectable devices:
  * `"app"` – Limits selection to devices belonging to your app.
  * `"global"` – Allows selection from all Homey devices, only makes sense if the app has the necessary `homey:manager:api` permission.

Additionally, an **optional** `filter` property can be used to limit the selection to specific devices:

* **`filter` (object, optional)** – Defines selection criteria:
  * **`class` (string, optional)** – Filters devices by their device class (e.g., `"socket"`, `"light"`, `"sensor"`).
    * Supports multiple values using a **pipe (`|`)** as an **OR** separator (e.g., `"socket|light"` allows selecting both sockets and lights).
  * **`capabilities` (string, optional)** – Filters devices based on required capabilities (e.g., `"onoff"`).
    * Supports:
      * **OR (`|`)**: `"onoff|dim"` → Devices must have **at least one** of these capabilities.
      * **AND (`,`)**: `"onoff,dim"` → Devices must have **all** these capabilities.
      * **Combination (`|` and `,`)**: `"onoff,dim|light_mode"` → Devices must have **both** `onoff` and `dim` capabilities **OR** the `light_mode` capability.

Additionally, users can reorder selected devices via drag-and-drop.

<pre class="language-json" data-title="widget.compose.json"><code class="lang-json"><strong>{
</strong>  "name": {
    "en": "My Widget"
  },
  "devices": {
    "type": "global",
    "singular": false,
    "filter": {
      "class": "socket",
      "capabilities": "onoff"
    }
  },
  "settings": [
    {
      "id": "text",
      "type": "text",
      "title": {
        "en": "Text"
      },
      "hint": {
        "en": "Your number"
      }
    },
    {
      "id": "number",
      "type": "number",
      "title": {
        "en": "Number"
      },
      "hint": {
        "en": "Your number"
      }
    }
  ]
}
</code></pre>
