> For the complete documentation index, see [llms.txt](https://manual.bubble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual.bubble.io/help-guides/data/temporary-data/custom-states.md).

# Custom states

This section covers custom states, that are used to store temporary variables of different kinds

Custom states are variables you can save on any element on the page, including the page itself. They let you store data temporarily, which resets when the page reloads. This is useful when your app needs to remember something you don't need to keep permanently in the database.

{% hint style="danger" %}
Custom states aren't visible to your users directly, but they aren't a secure way to store sensitive data. Anything you put in a custom state, including its default value, can be read by the person using that device.
{% endhint %}

## What custom states do

Custom states have a few defining properties:

* They hold data only until the page reloads, at which point they reset to their default value (empty by default).
* They're hidden[^1] from the user, but you can reference them in any dynamic expression.
* They're stored client-side[^2], which makes them faster than reading from and writing to the database.
* They can hold any kind of data: basic types like text, numbers, and dates, option set options, and custom data types. They can also hold lists.
* Each custom state belongs to an element, and you can create as many as you need on any element, including the page itself.

You can store any kind of Bubble data in a custom state, from a simple text value to a data type like a specific user or a shopping cart, anything you'd like your app to remember for the moment.

With a list, a custom state can track several pieces of data at once. For example, you can track which items a user selects in a repeating group by adding each one to the custom state's list.

## Creating a custom state

Any element can hold a custom state, and it's up to you to decide which element is the most appropriate to store it on. There are two ways to create one.

### With an action

{% stepper %}
{% step %}

#### Add the action

Add the **Set state of an element** action to a workflow.
{% endstep %}

{% step %}

#### Create the state

Pick the element (the page called *my-page* in the example), then click the + icon (2). Any existing custom states on that element will appear as an option. In this case there is no existing custom state. Click *Create a new custom state* to create on.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F1GyNkYxPbcqQBtIpTjAK%2Fcreate-custom-state.png?alt=media&amp;token=742ec848-8f74-4904-9d88-6e41e9a74d1b" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Set the name and type

Give the custom state a suitable name, and pick the data type it should hold.
{% endstep %}
{% endstepper %}

### Directly on an element

{% stepper %}
{% step %}

#### Select the element

Select the element that you want to add a custom state to. in this example, we've selected the page, called *my-page*. Then, click the custom state icon in the upper right corner of the element property editor.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FM7SvFLouFH4FpxuJik87%2Fcreate-custom-state-on-element.png?alt=media&amp;token=63022cf1-fc5d-4f2b-88c7-201c963fd6aa" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Create the state

Clicking the icon opens up the custom states already stored on that element.&#x20;
{% endstep %}

{% step %}

#### Set the name and type

Give the custom state a suitable name, and pick the data type it should hold.
{% endstep %}
{% endstepper %}

## Finding, editing, and deleting a custom state

You can use the element inspector to find, edit, and delete the custom states on an element. Click the information icon, as shown in the animation above.

A custom state's name updates everywhere in your app automatically, so it's safe to change. You can also change its data type or delete it, though both can create errors in the issue tracker if they leave a workflow or expression broken.

## Assigning a value to a custom state

There are two ways to give a custom state a value:

{% stepper %}
{% step %}

#### Set a default value

Follow the steps in the guide above to open up the custom state editor from the element property inspector. In the example below we have a custom state called `my-custom-state`, of type *text*, holding the default value `my-text`

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FHkMn9BjUFf1uPMDMEHyl%2Fset-default-value-custom-state.png?alt=media&amp;token=6ea51faf-56f8-4389-b17b-53f942810fda" alt="The Custom States panel showing one state: type text, name my-custom-state, default value my-text, with an unchecked List box."><figcaption><p>The Custom States panel in the element inspector. Here, a text state named <code>my-custom-state</code> has the default value <code>my-text.</code></p></figcaption></figure>
{% endstep %}

{% step %}

#### Use the *Set state of an element* action

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FbUVGJb2n9eKfwKg8pHyL%2Fset-state-with-action.png?alt=media&amp;token=fc24af0b-a637-499a-917a-948d7c6d2519" alt="A workflow with a Set state of an element action. Its property panel sets the element to my-page and the custom state my-custom-state to my-text."><figcaption><p>The <em>Set state of an element</em> action assigning the value <code>my-text</code> to the my-custom-state state on my-page.</p></figcaption></figure>

Assign a value with the *Set state of an element* action. This works for any value, including dynamic ones.
{% endstep %}
{% endstepper %}

Each time you assign a value to a state, its previous value is overwritten.

{% hint style="info" %}
Custom states don't update automatically when database records are deleted. If you store a list of things in a custom state and one of those things is later deleted from the database, the list still shows the same item count, and the fields on the deleted record show up empty.

You can work around this by filtering the list in any expression that counts it, for example `My element's custom state list:filtered [Creation Date is not empty]:count`.
{% endhint %}

## Other ways to learn

<details>

<summary>Video lessons</summary>

* [How to use custom states](https://youtu.be/ydqXrIgTekE)

</details>

[^1]: Custom states are hidden by obfuscation, which doesn't make them truly inaccessible to a user. Obfuscation is not security, so don't place any value in a custom state that you wouldn't be comfortable sharing with your app's users.

[^2]: *Client-side* means on the user's device, as opposed to on Bubble's servers. For custom states, it means the states are held in the memory of the user's device and aren't sent to the server.
