---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.3
alternate:
  - https://divkit.tech/docs/en/concepts/variables.md
  - https://divkit.tech/docs/ru/concepts/variables.md
---
> **Documentation Index:** Fetch the complete configuration index at https://divkit.tech/docs/en/llms.txt

# Variables

To use variables, declare them in a separate `variables` block in the card root. When declaring a variable, specify the following parameters:

- `name`: Name, which can consist of uppercase and lowercase Latin characters, digits, and the characters `_` and `.`. It can't start with a digit or a dot.
- `type`: Type of variable. See [Data types](#types).
- `value`: Default value.

For example:

```json translate=no
{
    "variables": [
        {
            "name": "subscribed",
            "type": "boolean",
            "value": true
        }
    ],
}
```

## Data types {#types}

Supported data types:
- Boolean: `boolean`
- String: `string`
- Integer: `integer`
- Floating-point number: `number`
- Color: `color`
- Link to resource: `url` (must be a valid URL)
- Dictionary: `dict`
- Array: `array`


{% cut "Examples of expression in variables initialization" %}


```json translate=no
{
    "variables": [
        {
            "name": "subscribed",
            "type": "boolean",
            "value": true
        },
        {
            "name": "likes",
            "type": "integer",
            "value": 0
        },
        {
            "name": "black",
            "type": "color",
            "value": "#f000"
        },
        {
            "name": "username",
            "type": "string",
            "value": "unknown"
        }
    ],
    "states": [ ... ]
}
```


{% endcut %}


## Expressions in Variable Initialization {#expressions}

Variables support expressions in their initialization values. This allows you to reference other variables or use functions when defining a variable's initial value. The expression is evaluated once at the moment of variable initialization. The order of declaration matters - a variable can only reference variables that were declared before it.
{% cut "Expressions in variable initialization example" %}

```json translate=no
{
  "variables": [
    {
      "name": "margin",
      "type": "integer",
      "value": 8
    },
    {
      "name": "padding",
      "type": "integer",
      "value": "@{margin * 2}"
    },
    {
      "name": "total_spacing",
      "type": "integer",
      "value": "@{margin + padding}"
    }
  ]
}
```

{% endcut %}

{% note warning %}

Avoid circular references between variables. If a variable references itself directly or indirectly through other variables, it will result in an initialization error.

{% endnote %}


## Dictionaries {#dictionary}

One of the available variable types is dictionaries. These are custom JSON objects that can store variables of any other type.
For instance, dictionaries are useful for declaring palettes and retrieving their values depending on the app theme:

```json translate=no
"variables": [
  {
    "name": "palette",
    "type": "dict",
    "value": {
      "light": {
        "text_color": "#ffffff",
        "text_background": "#0077FF"
      },
      "dark": {
        "text_color": "#000000",
        "text_background": "#0077FF"
      },
      "big": {
        "text_size": 20
      },
      "small": {
        "text_size": 16
      }
    }
  },
  {
    "name": "app_theme",
    "type": "string",
    "value": "light"
  },
  {
    "name": "font_size",
    "type": "string",
    "value": "small"
  }
]
```

Dictionaries can't identify types automatically, so you need to use appropriate functions to retrieve their values:

```json translate=no
getIntegerFromDict(dict_name, path_to_value)
getNumberFromDict(dict_name, path_to_value)
getStringFromDict(dict_name, path_to_value)
getColorFromDict(dict_name, path_to_value)
getUrlFromDict(dict_name, path_to_value)
getBooleanFromDict(dict_name, path_to_value)
getOptIntegerFromDict(fallback, dict_name, path_to_value)
getOptNumberFromDict(fallback, dict_name, path_to_value)
getOptStringFromDict(fallback, dict_name, path_to_value)
getOptColorFromDict(fallback, dict_name, path_to_value)
getOptUrlFromDict(fallback, dict_name, path_to_value)
getOptBooleanFromDict(fallback, dict_name, path_to_value)
```

With the dictionary declared in the example, you can use color and font size values as follows:

```json translate=no
"background": [
  {
    "type": "solid",
    "color": "@{getColorFromDict(palette, app_theme, 'text_background')}"
  }
],
"font_size": "@{getIntegerFromDict(palette, font_size, 'text_size')}",
"text_color": "@{getColorFromDict(palette, app_theme, 'text_color')}"
```

{% cut "View an interactive example" %}

<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/variables_1.json" width="700" height="500" frameborder="1"></iframe>


{% endcut %}


## Arrays {#array}

Arrays contain arbitrary JSON objects.

```json translate=no
"variables": [
  {
    "type": "array",
    "name": "array",
    "value": [
      "string",
       123,
      "@{expression}"
    ]
  }
]
```
Same as dictionaries, arrays can't identify the types of their elements automatically, so you need to use appropriate functions to retrieve their values:

```translate=no
getIntegerFromArray(array, index)
getNumberFromArray(array, index)
getStringFromArray(array, index)
getColorFromArray(array, index)
getUrlFromArray(array, index)
getBooleanFromArray(array, index)
getArrayFromArray(array, index)
getDictFromArray(array, index)
getOptIntegerFromArray(array, index, fallback)
getOptNumberFromArray(array, index, fallback)
getOptStringFromArray(array, index, fallback)
getOptColorFromArray(array, index, fallback)
getOptUrlFromArray(array, index, fallback)
getOptBooleanFromArray(array, index, fallback)
getOptArrayFromArray(array, index, fallback)
getOptDictFromArray(array, index, fallback)

len(array)
```

Using an incorrect function type or attempting to access an index outside the bounds of the array will result in an error. To avoid this, consider using the `getOpt*` function instead of `get*`. In this case, the `fallback` value will be returned instead of the error.

{% cut "View an interactive example" %}

<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/variables_2.json" width="700" height="500" frameborder="1"></iframe>

{% endcut %}


## Changing the values of variables {#modify}

To change the value of a variable, use the `set_variable` [action](https://divkit.tech/docs/en/concepts/interaction.md). For example:

```translate=no
div-action://set_variable?name=common_text_size&value=17
```

To set the value for a variable, you can use [calculated expressions](https://divkit.tech/docs/en/concepts/expressions.md) and [built-in functions](https://divkit.tech/docs/en/concepts/functions.md).

{% note info %}

The type of a new value must match the variable type, otherwise the value can't be applied.

{% endnote %}

{% note info %}

You can use element-level local variables in URL actions. For example, to set a global variable based on a local variable value:

```translate=no
div-action://set_variable?name=result&value=@{local_value}
```

{% endnote %}


Examples:

- Change the value of a floating-point variable:

    ```translate=no
    div-action://set_variable?name=price&value=3.889
    ```

- Change the value of a boolean variable:

    - `true`: `div-action://set_variable?name=is_liked&value=1` or `div-action://set_variable?name=is_liked&value=true`
    - `false`: `div-action://set_variable?name=is_liked&value=0` or `div-action://set_variable?name=is_liked&value=false`

- Change the `color` type variable to green:

    ```translate=no
    div-action://set_variable?name=color_variable&value=@{encodeUri('#ff00ff00')}
    ```


- Setting dictionary variables with expressions:

    ```translate=no
    div-action://set_variable?name=result_dict&value=@{source_dict}
    ```

    Or using typed action format:

    ```json translate=no
    {
      "type": "set_variable",
      "variable_name": "result_dict",
      "value": {
        "type": "dict",
        "value": "@{source_dict}"
      }
    }
    ```

    {% note info %}

    The dictionary expression must evaluate to a valid dictionary value that matches the target variable type.
    
    {% endnote %}

- Setting dictionary variables from JSON objects:

    Dictionary variables can be updated using typed actions with the dictionary value directly:
    
    ```json
    {
      "log_id": "set_palette",
      "typed": {
        "type": "set_variable",
        "variable_name": "palette",
        "value": {
          "type": "dict",
          "value": {
            "light": {
              "text_color": "#e0bae3"
            }
          }
        }
      }
    }
    ```

    {% cut "URL-encoded example" %}

    Dictionary variables can also be updated by providing a properly URL-encoded JSON string representation:
    
    ```translate=no
    div-action://set_variable?name=palette&value=%7B%22light%22%3A%7B%22text_color%22%3A%22%23e0bae3%22%7D%7D
    ```
    
    This corresponds to the following JSON structure:
    ```json
    {
      "light": {
        "text_color": "#e0bae3"
      }
    }
    ```

    {% endcut %}



## Global variables {#global}

Variables that are declared within a layout are local and can't be accessed externally. To share variables between different layouts, use global variables.

To do this, declare a `DivVariableController` object on the client side and pass it the variables that need to be accessed from the layout.

## Stored values {#stored-values}

Stored values allow you to save data between user sessions. Unlike regular variables, stored values are saved on the device and remain available after the app is restarted.

### Stored value scopes

Stored values support different scopes:

- `global` — values are available in all app cards
- `card` — values are available only in the current card
- `default` — uses the default scope (equivalent to `global`)

If the scope is not specified, `global` is used by default.

### set_stored_value action

To save values, use the `set_stored_value` action:

```json translate=no
{
  "type": "set_stored_value",
  "key": "user_preference",
  "value": "dark_theme",
  "scope": "global"
}
```

Action parameters:
- `key` — key for saving the value
- `value` — value to save (string, number, array, dictionary)
- `scope` — scope (`global`, `card`, `default`)
- `lifetime` — value lifetime in seconds (optional)

### Functions for reading stored values

To read stored values, use the following functions:

- `getStoredStringValue(key, fallback, scope)` — read string value
- `getStoredArrayValue(key, fallback, scope)` — read array
- `getStoredDictValue(key, fallback, scope)` — read dictionary

The `scope` parameter is optional. If not specified, the default scope is used.

{% note info %}

The `set_stored_value` action and functions for reading stored values are supported on Android, iOS, and Web platforms.

{% endnote %}

{% cut "Stored values usage example" %}

```json translate=no
{
  "variables": [
    {
      "name": "theme",
      "type": "string",
      "value": "@{getStoredStringValue('user_theme', 'light')}"
    }
  ],
  "states": [
    {
      "state_id": "default",
      "div": {
        "type": "container",
        "items": [
          {
            "type": "text",
            "text": "Current theme: @{theme}",
            "actions": [
              {
                "log_id": "switch_theme",
                "typed": {
                  "type": "set_stored_value",
                  "key": "user_theme",
                  "value": "@{theme == 'light' ? 'dark' : 'light'}",
                  "scope": "global"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}
```

{% endcut %}

{% cut "Example with different scopes" %}

```json translate=no
{
  "variables": [
    {
      "name": "global_setting",
      "type": "string", 
      "value": "@{getStoredStringValue('global_setting', 'default_value', 'global')}"
    },
    {
      "name": "card_setting",
      "type": "string",
      "value": "@{getStoredStringValue('card_setting', 'card_default', 'card')}"
    }
  ],
  "states": [
    {
      "state_id": "default",
      "div": {
        "type": "container",
        "items": [
          {
            "type": "text",
            "text": "Global setting: @{global_setting}",
            "actions": [
              {
                "log_id": "set_global",
                "typed": {
                  "type": "set_stored_value",
                  "key": "global_setting",
                  "value": "new_global_value",
                  "scope": "global"
                }
              }
            ]
          },
          {
            "type": "text", 
            "text": "Card setting: @{card_setting}",
            "actions": [
              {
                "log_id": "set_card",
                "typed": {
                  "type": "set_stored_value",
                  "key": "card_setting",
                  "value": "new_card_value",
                  "scope": "card"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}
```

{% endcut %}

{% cut "Example for Android" %}

Declare `DivVariableController` when creating `DivConfiguration`:

```Kotlin translate=no
val variableController = DivVariableController()
val configuration = DivConfiguration.Builder(imageLoader)
    .divVariableController(variableController)
    .build()
```

Now you can pass a variable to the controller. For example, let's pass the string variable `app_theme`:

```Kotlin translate=no
val theme = Variable.StringVariable("app_theme", "light")
variableController.putOrUpdate(theme)
```

Now all `Div2View` created using this `DivConfiguration` will have access to the `app_theme` variable. You can change a variable's value via the `DivVariable#set` method or `DivVariableController#putOrUpdate`. If this variable is already declared in the controller, its value will also be updated.

{% endcut %}


{% cut "Example for iOS" %}

Declare global variables storage and `DivVariablesStorage` in `DivKitComponents`:

```Swift translate=no
let applicationStorage = DivVariableStorage()
let variablesStorage = DivVariablesStorage(outerStorage: applicationStorage)
let divkitComponents = DivKitComponents(variablesStorage: variablesStorage)
```

Now you can pass a variable to the global storage. For example, let's pass a dictionary with a palette:

```Swift translate=no
let themeVariable: DivVariables = [
  DivVariableName(rawValue: "palette"): .dict([
    "text_color": "#ffffff",
    "text_background": "#0077FF"
  ])
]
applicationStorage.put(themeVariable)
```

Now all `DivView` created using this `DivKitComponent` will have access to the `palette` variable.

DivKit uses two types of storages:

- `DivVariableStorage` — base storage for variables. Use it for global application variables. It has `put()` method to add variables and supports creating storage hierarchies through `outerStorage`.

- `DivVariablesStorage` — manager for variables at `DivKitComponents` level. It manages card-level variables through `set(cardId:variables:)` and `append(variables:for:)` methods. Can have `outerStorage` of type `DivVariableStorage` for accessing global variables.

{% endcut %}

{% cut "Example for Web" %}

Create `GlobalVariablesController`:

``` js translate=no
import {createVariable, createGlobalVariablesController} from '@divkitframework/divkit';

const controller = createGlobalVariablesController();
```

Now you can pass a variable to the controller. For example, let's pass a dictionary with a palette:

``` js translate=no
const palette = createVariable('palette', 'dict', {
  "text_color": "#ffffff",
  "text_background": "#0077FF"
});
controller.setVariable(palette);
```

Now all class instances created using this `controller` will have access to the `pallete` variable.

{% endcut %}

{% note alert %}

Local variables are given precedence over global ones. If you declare a local variable that shares the same name as a global one, the global variable will be inaccessible. In addition, modifying a global variable from a layout changes it in `DivVariableController`, which means the variable will also change for all other layouts where it's used.

{% endnote %}

## Running actions when changing variable values {#actions}

When changing the variable value (except for updating all properties where the variable is used), any number of [actions](https://divkit.tech/docs/en/concepts/interaction.md) can be run. Add the trigger description in `variable_triggers`:

- `condition`: A condition for running the action. It can contain a boolean expression using variables or trigger events.
- `mode`: Determines when the action triggers:

    - `on_condition`: The action is triggered when a change in the variable results in a certain condition being met (the condition wasn't met until the action occurred).
    - `on_variable`: The action is triggered every time the condition is met when the value of the variable changes.

    For example, suppose the variables change several times, with `condition` returning `true → true → false → true`. When using `on_condition`, the action triggers two times, while with `on_variable` it triggers three times.

- `actions`: Describes [actions](https://divkit.tech/docs/en/concepts/interaction.md) that must be run when the condition is met.

Limitations:

- Conditions that don't contain variables (such as `"condition": "@{1 == 1}"`) or contain functions that don't depend on variables **won't work**, because variables determine when to run the condition check.
- The trigger won't start if the compared entities in the condition have different types (for example, if a boolean variable is compared with an `integer` variable).

For example:

```json translate=no
{
    "states": { ... },
    "variables": { ... },
    "variable_triggers": [
        {
            "condition": "@{liked}",
            "actions": [
                {
                    "url": "div-action://set_variable?name=total_likes&value=@{sum(total_likes, 1)}"
                }
            ]
        },
        {
            "condition": "@{subscribed && !liked}",
            "mode": "on_condition",
            "actions": [
                {
                    "url": "div-action://set_state?state_id=0/subscriptions/expanded"
                },
                {
                    "log_id": "common_posts_shown",
                    "url": "div-action://set_state?state_id=0/common_posts/collapsed"
                }
            ]
        },
        {
            "condition": "@{total_likes > 100 || user_name == 'John'}",
            "mode": "on_variable",
            "actions": [ ... ]
        }
  ]
}
```
In the example above, the first trigger runs the action that increases the `total_likes` variable value each time the `liked` variable value changes from `false` to `true`. The second trigger follows the same logic.

Because of the `"mode": "on_variable"` parameter, the third trigger fires every time the variable values are changed and the `condition` is met.

## Methods {#methods}

For working with arrays and dictionaries, it's convenient to use methods. Unlike functions, methods are called directly from an array or dictionary and return the required value.

#### Available methods

#|
|| Name | Description | Result type ||
|| `toString` | Converts the value of a variable of any type to a string. | `string` ||
|| `getArray` | Allows you to get an array from a dictionary (array) by key (index). | `array` ||
|| `getDict` | Allows you to get a dictionary from a dictionary (array) by key (index). | `dict` ||
|| `getBoolean` | Allows you to get a boolean value from a dictionary (array) by key (index). | `boolean` ||
|| `getColor` | Allows you to get a color value from a dictionary (array) by key (index). | `color` ||
|| `getInteger` | Allows you to get an integer from a dictionary (array) by key (index). | `integer` ||
|| `getNumber` | Allows you to get a floating-point number from a dictionary (array) by key (index). | `number` ||
|| `getString` | Allows you to get a string from a dictionary (array) by key (index). | `string` ||
|| `getUrl` | Allows you to get a URL from a dictionary (array) by key (index). | `url` ||
|| `isEmpty` | Checks if an array (dictionary) is empty and returns the corresponding boolean value. | `boolean` ||
|#

Complete descriptions of method fields and usage examples are available in the [DivKit repository](https://github.com/divkit/divkit):

* `toString`: [fields](https://github.com/divkit/divkit/blob/main/test_data/expression_test_data/methods_signatures.json), [examples](https://github.com/divkit/divkit/blob/main/test_data/expression_test_data/methods.json);

* methods for arrays: [fields](https://github.com/divkit/divkit/blob/main/test_data/expression_test_data/methods_signatures_array.json), [examples](https://github.com/divkit/divkit/blob/main/test_data/expression_test_data/methods_array.json);

* methods for dictionaries: [fields](https://github.com/divkit/divkit/blob/main/test_data/expression_test_data/methods_signatures_dict.json), [examples](https://github.com/divkit/divkit/blob/main/test_data/expression_test_data/methods_dict.json).

{% cut "Field values" %}

The method description includes the following fields:

* `function_name` — method name.

* `is_method` — flag indicating whether the function is a method. For all methods, it has the value `true`.

* `doc` — description of how the method works.

* `arguments` — list of arguments. Each argument is described by the values:

  * `type` — type;

  * `doc` — description;

  * `vararang` — optional flag allowing this argument to accept not one, but multiple values of the required type.

* `result_type` — type of the returned value.

{% endcut %}

{% cut "View an interactive example" %}

<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/variables_3.json" width="700" height="500" frameborder="1"></iframe>

{% endcut %}

## Element-level variables {#local}

Element-level variables are declared in the layout within the element they characterize.

{% note info %}

Previously, only card-level variables (for the `card` object) could be declared. Now variables can be declared for any element.

{% endnote %}

{% cut "View an interactive example" %}

<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/variables_4.json" width="700" height="500" frameborder="1"></iframe>

{% endcut %}

## Element-level triggers {#local-triggers}

Element-level triggers are activated when the value of an [element-level variable](#local) changes. Their format is the same as for [global triggers](#actions).

An element-level trigger:

* has access to element-level variables of the parent object;

* is triggered even for invisible elements (with the parameter `"visibility" = "gone"/"invisible"`);

* is not triggered in states and tabs that are not currently active;

* when used within [item_builder](https://divkit.tech/docs/en/concepts/item_builder.md) prototypes, has access to the current item data through the variable specified in `data_element_name` and the current item index through the `index` variable.

When transitioning to a new state or another tab:

* if the state (tab) is activated for the first time, the trigger fires when the condition in `condition` is met;

* if the state (tab) has already been initialized and the condition was not met before exiting it, the trigger will fire when the condition starts to be met.

## Variables for tracking element state {#element-state-variables}

Some DivKit elements provide special variables for tracking their state. For example, the `div-pager` element allows tracking the number of elements through a variable:

### Tracking the number of elements in a pager

The `div-pager` element supports the `item_count_variable` property, which allows you to specify the name of the variable for storing the number of pager elements available to the user.

```json translate=no
{
  "type": "pager",
  "item_count_variable": "pager_item_count",
  "items": [
    {
      "type": "text",
      "text": "Page 1"
    },
    {
      "type": "text", 
      "text": "Page 2"
    }
  ]
}
```

When the pager is initialized, the specified variable will be set to the number of elements. This is useful for creating progress indicators or displaying the current position:

```json translate=no
{
  "variables": [
    {
      "name": "pager_item_count",
      "type": "integer",
      "value": 0
    }
  ],
  "states": [
    {
      "state_id": "default",
      "div": {
        "type": "container",
        "items": [
          {
            "type": "text",
            "text": "Total pages: @{pager_item_count}"
          },
          {
            "type": "pager",
            "item_count_variable": "pager_item_count",
            "items": [ ... ]
          }
        ]
      }
    }
  ]
}
```

{% cut "View an interactive example" %}

<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/variables_5.json" width="700" height="500" frameborder="1"></iframe>

{% endcut %}

<!-- source: en/_includes/index/troubleshooting.md -->
## Learn more {#troubleshooting}

You can discuss topics of interest in the DivKit user community in Telegram: [https://t.me/divkit_community_en](https://t.me/divkit_community_en).



[DivKit Repository](https://github.com/divkit/divkit)
<!-- endsource: en/_includes/index/troubleshooting.md -->
