How to Use Custom States in Bubble.io (Complete Guide)

Throughout this guide, you’ll learn everything there is to know about using custom states within Bubble’s no-code platform. This guide will cover:

  1. What are custom states and when you should use them
  2. How to use custom states to create a dark mode feature
  3. How to use custom states to create a navigation menu
  4. How to store data in a custom state, then pass this onto the database

Full Transcript of Tutorial

1. What are custom states

If you’re new to using custom states, the best explanation is that they’re a way to temporarily store data within a page or an element.

This can be quite helpful if you’d like to change the behavior of some elements, or even store data without having to make changes to your database. 

This guide will walk you through the three most common use cases for leveraging custom states in Bubble. 

One will be to create a dark mode switch in an application – so it gives users the ability to turn on or off dark mode. The next is the ability to create a navigation experience using tabs, and the last will temporarily store data on a page, then save that information into your database.

Between all three use cases, they’re going to give you a great understanding of how you can start to leverage custom states within your own Bubble application.

Let’s open up a Bubble editor and I can start walking you through the process.

2. How to create a dark mode feature using custom states

The first use case that I wanted to highlight was creating a toggle that enables or disables a dark mode feature. This example is quite popular because most applications these days offer some sort of dark mode experience. I also know it’s something that a lot of Bubbler developers like to add to their applications.

For the sake of that demo here, I’ve just created a static home page within my own Bubble editor. One thing I would just like to point out is that I’ve installed a toggle plugin which you’ll be able to see under my input forms here. I’ve installed the free ‘better toggle’ plug-in.

One thing I would just like to note is that I have set the value of this plugin to equal ‘no’ by default. I’m doing this because I don’t want my dark mode to be activated as soon as the page is loaded.

When it comes to custom states, the purpose is to avoid storing data within the actual database itself. Instead, we’re going to need to set the state on an element within our Bubble editor. The element in this case is going to be the actual page itself. 

If I select my white background and just open up my element inspector. This is where I’ll be setting my custom state.

One thing I should also mention is that it’s also possible to store a custom state on absolutely any element. For example, you could store a custom state within a group, a text element, or even an image.

I can vividly remember the first time I ever created a custom state within Bubble. The most confusing aspect was trying to comprehend where the actual custom state was stored.

If you’ve ever opened up the workflow editor, you’ll know that you can set custom states within a workflow, but in my opinion, the easiest way to create a custom state is by selecting the element itself.

Once you’ve selected an element, you can select the information icon in the top right-hand corner. When you open this menu, you’ll see an option to add a custom state to this specific element. 

What you’ll find is that the process of creating a custom state is much the same as creating a data field within your database. You’ll first need to give it a name. In this case, I’m going to be calling my state ‘dark mode’. 

From here, you’ll need to give your state a type. Similar to a data field, this is the type of data that you would like to store within your state. Let’s say, for example, you wanted to store some text or some images temporarily on your page – you could select those as the state type. 

In my case though, I want my state type to be a ‘yes or no’ option because I’d like my page to be in dark mode, or to not be in dark mode.

So I’m going to select that this is a ‘yes or no’ value. And I’ll be showing you later on in another example how we can choose different state types and also choose the multiple entries option, but for now, I’m just going to set this dark mode state as ‘yes or no’. 

Once I’ve created this state, I’m then going to set the default value to be ‘no’. I’m doing this because I don’t want my page to automatically be set in dark mode. I’ll only want it to be changed when a user actually selects to toggle dark mode on.

I’m then going to close my information column, then I’m going to also close my element inspector. What I’d like to do now is create a workflow that responds to this toggle element every single time it’s toggled on or off. 

Of course, when it’s toggled on, I’m going to want to change the dark mode state of my page to be ‘yes’. Then, when it’s toggled off, I’ll be turning it back to ‘no’.

If I open my workflow editor, I’ll choose to trigger an event from our element triggers. The trigger will recognise when the ‘better toggle’ value is changed. When the value has changed, what I’d like to do is set the state of my page. 

I’m going to scroll on down to the element actions menu here and choose the set state option. Now you’ll find that you have the option to choose from which element you’d like to set the state within. 

If you remember, our custom state has been added to the page as a whole. This means I’ll select from the dark mode element which was of course my whole page. I’m then going to set the value of this to be ‘yes’, which means it’s going to now update the page state to be set into dark mode.

One thing I would just like to note though is that I’m going to need to add a condition on my workflow trigger. I’m doing this because I’d only like this workflow to run when the current dark mode state is set to ‘no’. 

I’m going to add a condition here that only allows this to run only when the page as a whole has its custom state value set as ‘no’.

I’ll then also need to create another workflow that just allows us to turn the dark mode state off. To achieve this, I’m going to create a new workflow once again. In this workflow, I’ll recognise when the ‘better toggles’ value is changed again.

In this case, I only want this workflow to run when the toggle is switched across to ‘yes’, meaning we are actively viewing the platform within dark mode. I’m going to create a condition and recognize when the dark mode page, when it’s dark mode state is currently ‘yes’. When this is true, this workflow will then run.

For this workflow, I’ll once again head down to my element actions option and choose to set the state of an element. The element is of course our dark mode page. The custom state I’ll be setting is my ‘dark mode’ state, only this time, I’ll be switching the value of this to ‘no’. 

Now what we can do is create an experience that allows our page to respond to the current custom state that’s been stored on our page. As we’re currently viewing this page, this is how it’s going to look in light mode, but what I’d like to do is update aspects like the background color, as well as the text color once the page is set to dark mode. 

In order to create this experience I’m going to start by selecting my page element itself. Now, I can create a condition on this page that reflects the value of the custom state that’s stored on it. 

If I head to my conditional tab, I’ll choose to define a new condition and I’ll recognize when our dark mode state is set to ‘yes’, in which case, I’ll be updating the background color of this page. 

I’m going to need to scroll on down to the dark mode page itself and update the background color of this page. The color of the background will need to be a shade of black.

What I love about conditions in Bubble is that you have the ability to toggle these on and off to preview what the experience is actually going to look like when the condition is true. 

After I’ve updated the color of the background, I’m also going to need to update the color of my text. If I select my main heading, I’m going to once again define a new condition. In this condition, I’ll recognize when the dark mode page, when its ‘dark mode’ state is set to ‘yes’, I’m going to update the color of this text. 

Finally, I’ll also need to update the color of our body text. Instead of creating a condition for this manually, it’s also possible to copy and paste a condition between elements.

If we are to right-click on our text element here, we can actually choose to copy the conditional formatting. So we can just copy across the condition that we’ve added to this element. Then I’m going to select my text here, and I’m going to choose to paste that conditional formatting. And now it’s pasted across the very same condition, meaning that when the dark mode status is ‘yes’, it is going to update the color of this text. 

And that is all we’ll need to do in terms of creating a dark mode experience with our custom states.

Let’s quickly jump over to our Bubble preview to take a look at how this functions within a real-world application. 

Over in my Bubble development environment, because the default value of our dark mode state was set to ‘no’, we’re currently viewing the page in light mode. If I was to select my toggle, however, what you’ll see is that workflow will run and update the value of the custom state stored on the actual page itself.

As my custom state is updated, it will cause all of my conditions to change, which will then update the colors of my elements.

As of now, we can now see we have an active dark mode feature inside of our application.

3. How to use custom states to create a navigation menu

Jumping back into Bubble, there’s another great common use case I’d like to show you for utilizing custom states, and that’s how we can use the feature to build a navigation experience.

I’ve already gone ahead and created a separate page within my editor for the sake of this guide today. This page is a replicate of a user settings page within most modern apps.

Within the user interface of this page, I’ve allowed a user to access both their profile settings, as well as their business settings. 

I’ve called our first group the ‘user settings’ group. The purpose of this group is to store information that’s relevant to a user’s personal account. So this will store things like their name, their address, their age, and their height. 

I’ve also created a separate group called ‘business settings’. This group will be used to store information about a business. This will be things like their business name, the description of the business, as well as the industry of that business.

Now, what I’d like to do is create an experience where the ‘business settings’ group can actually sit over the top of our ‘user account settings’. Now, although these groups will overlap each other, only one group will be displayed at a time. To help determine which group should be displayed at any given time, I’d like to create two custom states on my page that recognize which tab a user has selected from our navigation menu.

If I once again select the page as a whole, I can select our information icon and choose to add a custom state to this element. 

The first state I’ll be creating is going to be called ‘display user settings’. This is going to be used to display the user settings group that I’ve created. This state type will be a ‘yes or no’ option – meaning we’re either going to display our user settings group or we’re not. 

Then, I’ll need to create our second custom state. This state will be called ‘display business settings’. Now, of course, this state will also be a ‘yes or no’ type once again. 

Before we build out the workflows to actually power this custom state, I’m just going to set the default value of our ‘display user settings’ state to be ‘yes’. 

As the page loads, what I’d like to do is actually display the user profile settings group first, and then of course, we can update that if a user selects to open up the business settings group. 

This means that we’ll need to do is create two separate workflows that can respond to whatever heading is clicked, then, we’ll display the relevant group when it’s needed.

So I’m just going to select my profile settings heading, then I’ll choose to start/edit a workflow whenever this element is clicked. Within this workflow, I’m going to be setting the state of our page. 

To do this, I’ll scroll to our element actions and choose to set the state. The element we’ll be setting the state of is our overall page. The custom state I would like to set is going to be our ‘display user settings’ state, and the value of this will need to be ‘yes’. This means that I would have turned the user settings group ‘on’.

What I’ll also need to do is ensure that I turn the ‘display business setting’ state off at the same time. I’m going to need to set yet another state within this workflow step. The custom state will once again be on our page navigation element. In this case, I’ll be selecting that the ‘display business settings’ state will need to be ‘no’. This just ensures that only one group will be displayed at a time – so whenever we enable one state, we’ll just need to ensure we disable the opposing option.

And of course, as you might remember, our page by default loads the ‘display user settings’ to ‘yes’. This means that if a user was to in fact select our profile settings text, this workflow just wouldn’t really change the custom states as the page is already set to this.

What I’d like to do now is create an opposing workflow that enables us to change the custom state when our business settings tab is selected. I’m going to start/edit another workflow. Yet again, I’ll be choosing to set the state of an element, so under our element actions, I’m going to choose to set the state. The element is of course our page navigation menu, and the state I’ll be setting is the ‘display business settings’ group. In this case, I’ll want this value to be ‘yes’. Then, of course, I’m going to need to disable my ‘display user settings’ group. So I’m going to set the custom state of our display user settings to now equal ‘no’.

Now that we’ve created two separate workflows that enable us to toggle between both options, the only remaining thing we’ll need to do is create some conditions on these groups to either hide or display them based on whichever state is active on our page. 

For our user settings group, I’m going to unselect that this element is visible on page load, meaning it will be hidden until the state of the user settings is ‘yes’. I’m also just going to choose to collapse this element’s height when it’s hidden. This will allow the element that sit below this to just move up accordingly and take the place of the hidden group.

To do this, on our user settings group, I’m just going to need to create a condition. Under our conditional tab, I’ll define a new condition and recognize when the overall page’s ‘display user settings’ state is in fact ‘yes’, what I’d like to do is change the behavior of this element.  For the behavior, I’ll select that this element is visible and tick that that should be true. 

Once we’ve added a condition on our user settings group here, we’re going to need to replicate this whole experience on our business settings group. So I’m going to head to our appearance tab and first of all unselect that this element is visible on page load, meaning that it will be hidden. Then I’m also just going to choose to collapse this element’s height when it is in fact hidden.

Then, over on the conditional tab once again, I’m just going to recognize when the overall page, when it’s ‘display business settings’ state is currently set to ‘yes’, I’d like to select that this element is visible and tick that this is true. And that’s all we’ll need to create for our navigation custom state experience. Let’s open up our Bubble development environment and take a quick preview at how this all functions.

Once I run a preview of my account settings page, the first thing you might notice is that our user profile settings group is automatically displayed. This is because we set the default value of its custom state to be ‘yes’. At the same time, because our business setting state is set to ‘no’, our group is currently hidden below it. 

Of course, if I then like to open up our business settings group, I can select our title, and that will, first of all, hide our user profile settings group, then display our business settings group. And then, of course, I can toggle back over to the previous option if I would like.

And that’s actually the whole process of creating a page navigation experience with custom states. Of course, you can use this across as many different tabs as you would like. This, in particular, is quite useful if you’re building a single-page application. So, if, for instance, you’re building a mobile app and you don’t want to direct people across different pages, you can just choose to hide and display groups and create your own page navigation experience quite easily.

4. How to store data in a custom state, then save that to your database

The very last custom state example I’d like to show you is something a little bit more extensive as it allows us to actually store data temporarily that we will then add to our database. 

In my application, I have a separate page that allows us to a new project within a project management app. So if I was using something like Monday.com or Trello and wanted to create a new team project, this page is where I’ll be doing that.

On the page, I have a series of fields. I’ve just got the title of the project and the description of the project. What I’d like to do is create a way to store the value of team members that should be added to this project. 

Now, the reason why I’m using a custom state to do this is because at this point, this new project does not exist in our database, so I can’t make changes to an existing entry. As an alternative, however, I can temporarily store data on my page using a custom state.

The experience I’m going to create will allow someone to use a search box element to search through all of the users in my database. When I select that I want to add a particular user to this project, I want to display them within my repeating group.

Now, I’ve set all of the data sources for both these elements to be blank because I want to walk you through the process in as much detail as possible. 

What I’m going to do is first is create the state itself where I’ll be storing the users that will eventually display in our repeating group.

I’m going to open up my page as a whole, then I’ll select the information icon and choose to create a new custom state. I’ll be calling this custom state ‘team members’. Now, what I’d like to do is store a list of all the team members that should be added to this final project. So for the state type, I would like this to be a list of users. I’m going to select from my user data type in my database, and I’m going to tick that this is a list with multiple entries because I want to add multiple users to a single project. I will then create that.

And now what I’d like to do is update the value that’s stored within our custom state every single time the value of our search box is changed. But before I do that, I’m just going to need to configure our search box to search through all the users in our database. From our dynamic choices, I’m going to search for all of the users and the field I’ll be searching through is their name. This will allow me to easily search and be prompted with predictive results based on the names that I search in my database. 

Now that I’ve configured my search box, I can create a workflow whenever the value of this search box is changed. To do this, I’ll jump into my workflow editor and create a workflow that’s triggered from an element option. I’d like to select that anytime an input value is changed, I’d like this workflow to run. The element in this case will of course be our search box. 

Within this workflow, I’d like to set the custom state stored on our overall page. The custom state I’ll be setting is the list of team members. And what I’d like to do is recognize the team members that have already been added to this custom state, and then add another user to this list.

I’m going to first need to identify all of the users set in our current custom state. So I’ll select from the ‘team members’ custom state, which if you remember is a list of users. Then once I’ve recognized all of the team members that have currently been added to our project, I’m going to select to plus an item. The item I’d like to add to this list will need to be a user, which of course is going to be the user within our search box. So I’ll select this search box’s value.

One thing I’d like to point out is the reason why I had to search through the list of existing team members that have been stored on this page’s custom state. That is because if I was just to add in the user who’s currently stored in our search box, every single time I add a new user, it’s just going to replace the existing user in it with the new person who’s being selected. So what I need to do is just recognize all of the team members that have already been added to that custom state, and then I’ll be adding an additional item to it. And of course, if you have no team members stored within your custom state, it’s just going to add in the very first entry.

After setting my custom state to actually store the users within my page, I can now display these users within a repeating group. If I head over to my design tab here, I have a blank repeating group. I’m going to need to set the type of content to be a user because I’d like to display a list of users. When it comes to the data source, I want to display the users who are currently stored in our page’s custom state.

For the data source, I want this to be the new project, which is my page as a whole, it’s team members custom state, which of course was a list of users. What I can now do is just add in the information I’d like to display of the users once they’re selected. So in this case, I’ll want to display a profile photo and their name. 

I’m going to select to add an image element into my first repeating group cell. I will insert dynamic data and I’ll display the current cell’s user and their profile photo. For a personal preference, I’m also going to set the roundness of this to 100. I’ll also just make sure that this image is a square, so I’ll set the width of this to 50 pixels and then the height to be 50 pixels. 

Next to the user’s profile, I just want to add a text element that will display the user’s name. To do this, I’ll insert dynamic data and display the current cell’s user, their name.

Now that we’ve covered how we can actually display a list of users who have temporarily been stored to the value of a custom state, what I’d now like to focus on is how we’ll store this data in our database.

When a user selects to create a new project, we’ll need to store some details like the title and description of it. What we’ll also need to store is the list of users within our repeating group.

To achieve this, I’ll choose to start/edit a workflow when our ‘create project’ button is clicked. In this workflow, I’m going to head to our data tab as we’re finally making an entry in our database. From this tab, I’ll select to create a new thing.

The thing I want to create is a new project. Now I’m just going to need to match all of the data fields in my database with the input fields on my page. So for the title, I want this to be the same value as the input title. For the description, I want this to be the value of my input description field. And now for our users, so the team members who have been added to this project, this will be the value of users stored in my custom state.

We can now preview how this is going to function within our application.

Over in the preview of my app, I’m just going to create a new project from scratch. I’ll call this a test project, then the description will be ‘this is a test project’.

The main thing I’m interested in showing you is just how the custom state’s going to work when we use our search bar. So I’m going to search through a user in my database called Eric Johnston. I’m going to choose to add him to this project, and because the value of this search box has been changed, that workflow has successfully run and it has stored the user in our page’s custom state. 

Of course, because the data source of our repeating group was referencing the custom state on our page, Eric’s profile photo and his name are now being displayed within it.

Let’s say I’d like to add another user. I have a person called Rachel Smith. I’m going to choose to add her to this project and she will also now be added to our repeating group, which is of course a reflection of all of the users stored in our custom state. 

From here, if I wanted to finally create that project, I could select our ‘create project’ button. This would trigger my workflow to run and a new project would be created within my database.

One thing I’d like to point out though is the only downside to using custom states. If a user was to refresh the page at any point in time, the value stored in the custom state would refresh.

Never miss a course 👇