A guide to advanced use of reusables

A recent thread about the Bubble editor becoming sluggish over time spawned another discussion: reusable elements can speed up the editing of complex pages significantly, but as it was rightly pointed out, they can also make the editing of an app a lot more complicated. Having worked on some very large one-page apps, I’ve become a reusable group proponent by necessity. It’s a fact of life at the current stage Bubble is in, that as the number of elements and workflows increases, the editor becomes increasingly unresponsive, sometimes to the point of being almost impossible to work with, until you restart your browser.

Splitting the page into reusable groups and editing them one by one, on the other hand, doesn’t balloon the RAM usage in the same way, even if the total number of elements remains the same (or is even slightly higher, as the reusable itself is also an element). How noticeable is the difference? Night and day, in my experience.

As the thread spawned a discussion on the pros and cons of reusables, I thought I’d create this thread to share some of my own findings and mistakes I’ve made along the way (of which there are many).

What’s the purpose of a reusable element?

In short, a reusable element, as the name suggests, is used to store any number of elements that are used more than once on your site. Let’s say your users can log in to your app on several different places, it makes sense to create a reusable element to avoid creating the signup form several times and updating every one of them when something changes.

So far, most of you will agree. In this thread though, I’ll be discussing using reusables for groups that are not necessarily used more than once.

Why use reusables that way?

There are two reasons to do this:

  • As mentioned in the thread opening, using reusables instead of creating all elements on the same page, drastically reduces the sluggishness of the editor
  • For me personally, working with isolated parts of the site in its own window, undisturbed by hundreds of elements that are irrelevant to what I’m currently doing, makes sense. It’s easier to find the right elements and workflows, organize custom workflows, and keep a sensible folder workflow folder structure.

Ok great, let’s all do that!

But yeah, there are drawbacks of course. Working with reusables require meticulous planning, and well… experience working with reusables. Make a mistake, and you can easily set yourself up for a painful number of hours correcting it and regretting decisions made way back in the day when this all seemed like a good idea. So what’s to make of it?

When to use reusables

Before even thinking about using reusables in this way, consider the following points, and only use it…

  • When you know that a page will become seriously complicated and from experience, you know it severely affects the performance of the editor
  • If you find yourself struggling to find the right element and workflow, and want to work with them in an isolated environment
  • You are confident enough in your own abilities with Bubble and reusables to know how to plan and execute it properly

When not to use reusables

  • If the page you’re working on is not particularly complex
  • If you’re inexperienced working with reusables
  • If, after reading this thread, or based on your own experience, this will add more complications to your development than you’re comfortable with – I find it useful, but you may find it a pain in the ass.

So why do reusables complicate things?

Bubble is all about referencing stuff. You reference elements, database entries, states, and workflows all the time, in actions, conditions, and everything else. Placed inside a reusable element, however, you lose that link. Any element/workflow/state inside of a reusable element is contained within its own universe, oblivious to what’s going on outside, with a few exceptions.

In other words, whenever you need to set up a condition, workflow action, or anything else that references an element inside a reusable, you’ll get stuck looking for it.

Working with reusables to speed up the editor can oftentimes lead to nested resuable groups, which makes the communication even harder, as you’ll have to work through several layers of states or custom workflows to get a response.

So how can reusables communicate with the outside world?

Plugins aside, there are three ways a reusable can communicate with elements outside of itself:

  1. States: States placed on the reusable group itself (not elements inside it) are available from both sides. In other words, you can set a state on a reusable group from both inside and outside of it, and reference this state in any way. This can be used to share info, trigger workflows or whatever kinky stuff you’re into.
  2. Custom workflows: custom workflows inside a reusable can be triggered from the outside. It does not work the other way however. You use the command “Trigger a custom event from a reusable element” to do this.
  3. URL parameters: URL parameters can, of course, be read and manipulated from inside a reusable too, opening another channel of communication

Strategically placing custom workflows

Some custom workflows are used all across your app, and one thing you want to avoid when working with reusables is to having to update a bunch of workflows whenever you change something in one of them. In this way, reusables can come in very handy. Set up a reusable popup containing the workflows you need, and place that popup in any reusable where you need the workflow. Use Trigger a custom event from a reusable element to execute whenever needed. If you need to pass information to the workflow, use states in the popup.

Replacing workflows with API workflows

For repeated workflows, you can also choose to schedule an API workflow instead of keeping the workflow on the page. This allows you to execute it from anywhere in your app, reusable or not. Naturally, you should know the usage and limitations of API workflows before choosing this solution.

Using plugins

There are two plugins in particular that have made life with reusables easier, both made by gaurav.

EnvVariables

The EnvVariables plugin let’s you place an element on a page that creates a global variable for you. What this means is that you can store any sort of information (text, number, date, data type, etc) in a named variable. How is this different from a state? In two ways:

  • The variable is global, meaning that it can be referenced from anywhere, even reusables and nested reusables
  • It can be autobound, meaning that it will auto-update whenever data is updated or a set of conditions change (unlike states)

Pitfalls:

  • Whenever a EnvVariable is invisible, it doesn’t auto-update, meaning you will sometimes be confused by en empty value. Working with reusable elements in the way we’re talking about here usually means that they’re going to be going back and forth between visible and invisible states as your users use the app, meaning you may have to set up some custom workflows to update an EnvVariable element. How? By reassigning the value to the variable from where the data is supposed to be fetched, all visible EnvVariable elements will auto-update.

If-Then WF

As the name suggests, an If-Then WF allows you to set up a workflow to run whenever one or more conditions are met. One element can contain up to six different conditions and accompanying workflows. How is it different from Do when condition is true?

  • It can greatly reduce the number of workflows in your editor, because it allows you to pack six different conditions into one
  • For workflows needed across reusables, you can easily copy the element between groups, instead of having to manually copy a bunch of workflows
  • Somewhat unrelated to this discussion, the workflows can be triggered inside the cell of a Repeating Group, meaning you can reference elements in that cell from the workflow, even if the action is triggered by something outside of the RG.

Using the If-then WF plugin in combination with Env Variables can greatly increase efficiency when working with reusables.

Adding collapsible, invisible groups to speed up changes

We all know how painful it can be to move elements around once a page reaches a certain size. You want to add a simple input to a form, and suddenly you have to resize the page, move a shitload of groups downward to make room for the new input, move your floating groups that no longer align to bottom… I get a headache just thinking about it. Here’s what I do to avoid that:

  1. On every reusable, add a certain number of pixels to its height in addition to what’s needed for its content. I usually go with around 1500 pixels extra
  2. Add a group to the bottom of the reusable, with a height of 1500, invisible on page load and collapsed when hidden.
  3. This basically gives you 1500 extra pixels of wiggle room every time you change something. Instead of having to resize the reusable and every element underneath it on the page, you simply resize the collapsed group to make room.
  4. I sometimes place groups like this between certain elements on the page or in a reusable where I suspect I might want to make changes later. It adds minimally to the page load, and can save crazy amounts of time whenever changes are needed.

Conclusion

I’m currently finishing up a large project where reusable groups have been used all over the place to keep the editor lightweight and organize parts of the app in a way that makes sense to me and my collaborators. A sound question then, is would I choose to use reusables in that way again?

My personal response is, yes, I would. As long as it’s planned out in advance, and you know your way around the different methods, I don’t find reusables that hard to work with, to be honest. Still, like many other aspects of Bubble, in the end it’s up to your personal preferences and way of working. If this all sounds totally counter-intuitive, then by all means, ignore this thread and create awesome apps without it.

If this all seems interesting, on the other hand, I hope these tips can be of value.

Links:
If-then Workflow documentation | Plugin page (part of BDK Utilities)
Env Variables documentation | Plugin page

171 Likes

Hi @petter,

Great post.

There’s another one, cookies or browser storage. The one I use is (25$)

Browser Storage

Some have found how to read cookies with JS, but no other plugin seems to be available for free.

7 Likes

Cool, thanks for the tip, wasn’t aware of that one!

1 Like

First of all, thanks for taking the time to document this. I’m curious, does the use of reusables in this way benefit run-mode app performance in any way, or is this approach purely for edit-mode benefits?

2 Likes

Awesome post, @petter! I’ve been using reusables this way as well including adding that placeholder group at the bottom for future reference. Out of ten ‘pages’ on my one page app, two of them are not reusables.

And I use them for the same reason. It’s easier for my brain to keep track of workflows and elements in a contained scenario. If Bubble ever added the ability to assign ‘page sections’ on the page that would create a contained environment to work in that would be amazing. Until then reusables it is.

The Envariable plugin is incredible. Really takes away most of the shortfalls that applied to reusables. Most recently I’ve started using them to additionally pass current view and previous view states so I can add navigation across multiple reusables via states instead of getting url parameters.

I need to look at the If-then plugin though. That looks like it could really come in handy.

Thanks for the post. Really helpful!

6 Likes

@sudsy
Thanks! I can’t say for sure, and haven’t tested it performance-wise, but intuitively the answer is no, it probably doesn’t. If the reusable is used in more than one spot, sure, but in the way I’m describing it, probably not.

@eli
Thanks! You and me both! The app I’m working on right now consists of 11 pages and 91 reusables. So in this case, I really do put my money where my mouth is :joy:

2 Likes

:astonished: :joy:

1 Like

Thanks for putting this together. I’m sure it will help a lot of users. Not too much for beginners but definitely for the intermediate bubblers out there. Good job. :+1: Now I can easily link to this post when someone is talking about speeding up their apps. :grin:

3 Likes

Very good post. I bookmarked it for future reference.

2 Likes

An extra tip that I just remembered (can’t edit the post anymore), is to use always visible groups (typically a page header, footer or menu) to store important info in the global variables, and, when possible, If-then WF’s.

2 Likes

@petter
Thanks for this post. It is exactly what I needed. I had just finished putting together two different reusable elements that were nested and then placed onto a page. One of the reusable elements had a repeating group which contained the nested reusable element.

After setting everything up with custom states on the reusable elements and placing them on the page, my custom states were not accessible and I couldn’t do any of the work flows I was expecting to be able to do.

I do have one question about the plugins you mentioned. I can’t find the “If-then workflow” plugin.

What should I type to find it?

Cheers

Hey!

Glad it could help you out!

The If-then plugin is part of the BDK Utilities package (which contains several other very useful elements as well).

3 Likes

Ok, thank you.

1 Like

Hey @petter, thanks for this great post!

I am an avid reusable user, and I have something to add…

Triggering Events On The Page Which Uses the Reusable

So you have a reusable, and there is something on there a user can click on. Then you realise you want the result of that click to run a workflow on the page that uses the reusable. So a common situation for me is:

  • The main page, which instances:
  • “Listing Reusables” which lists things, for example client payments
  • “Editing Reusables” which allow you to edit a Thing, such as the payment or the contact’s details.

How can a click on part of the Listing Reusable open the appropriate Editing Reusable, when they are both instanced on the main page?

So I have two states on the Listing Reusable, for example:

  • Edit Contact (type yes/no, default = no)
  • Contact to Edit (type Contact)

In the Listing Reusable, when the user clicks on the contact’s name, the workflow does the following:

  • Sets Contact to Edit to the contact clicked on.
  • Sets Edit Contact to Yes, waits 500ms, then sets Edit Contact to No.

On the main page, I have an event:

When Listing Reusable’s Edit Contact is “Yes”… which:

  • Set Edit Contact’s Contact = Listing Reusable’s Contact to Edit.
  • Show Edit Contact Reusable.

Bob’s your Uncle, the Edit Contact Reusable opens up with the details of the contact you clicked on.

It works a treat! :slight_smile:

(“Bob’s Your Uncle” is an english phrase for “low and behold, a wonderful thing happens”…)

11 Likes

Thanks for sharing @antony :slight_smile:

Just released an update to the Env variables plugin to make using reusables even easier :smiley:

5 Likes

I am new to the Environment Variables plugin. I installed it hoping to use it for a specific use case involving a couple of reusables and pages but I’m having trouble accessing the value of the Env Variable (EV). I suspect that I’m just missing an obvious trick.

So my scenario is this. I have two pages A & B, a header which is a reusable and common to both pages and another reusable (a pop up) on only one of the pages (page B). I have placed an EV in the header. The user is sent to page A, with a URL that contains a parameter. When page A loads, I extract that parameter’s value and pass it to my EV. I had hoped that on page B, which also has the header, I would be able to retrieve the value of the EV and pass it (through a custom workflow) to my pop reusable, but from page B I cannot seem to reference the EV to get its value. The EV simply doesn’t come up as an option when trying to enter a dynamic value. In normal Bubble terms I wouldn’t expect it to, since it is not on the page but in a reusable but I thought this what the Environment Variable offered over and beyond standard Bubble elements?

Note that I see from the documentation that an EV’s value can also be accessed using code - window.getEnv(name), so maybe that’s the way to do it in this scenario but I don’t see a way to use that value after get it through code. There is no “Result of step x’s …” available.

Bumping this great thread to let the reusable lovers know that a new plugjn is around and might make life even better for you.
Check this out:

Cheers!

5 Likes

Great post! This seems to be the best resource for reusables, so I thought I’d ask the group for advice. And mainly I’m looking for confirmation, so that I’m more confident in taking the plunge to reusables.

My Question:
As I grow users on my application, should I use reusable elements?

Problem:
My single page app requires customization for each user. There’s no way around it.

When I get a new user, I create a new page by cloning the other page. I modify one section of the new page that requires customization. The more users I get, the more pages I need to manage. Adding a feature requires a build to one page multiplied by the number of users I have. This will eventually become chaos.

Why wouldn’t I use Reusable Elements?
I thought it was obvious that I’d go to reusable elements. But now I’m not sure.

  1. There’s not much info available (thanks for this post!)
  2. With the available info, the more I read the more I question if reusables are right for me.
  3. I have a complicated single page app. I understand that you can’t use a master page, or a reusable full page. I would need to build each new user’s page element by element if I used reusable groups.
  4. I’m not sure how reliable reusable groups are. I would need to convert sections to reusable groups and I’ve seen recent bugs with it.
  5. All of my groups pass data to each other - It seems complicated to pass data in and out of reusables.

Conclusion:
It sounds like setting up a new user would be more complicated with reusables. But it would pay off later in terms of updates and maintenance.

I want an easy to maintain system, where one update would apply to all pages.

The more users I get, the more complicated each updated gets. Each page is getting more and more out of sync.

It sounds like a lot of you had similar problems (specifically @Eli). And reusable elements were the solution.

I guess I’m just looking for confirmation in my thought process.

@brad.h Yes I agree, if you’re using the same backbone for every user and customizing off of that, then it sounds like the ideal use case for reusable to create a sustainable onboarding process. Just leave the customized part in your main app.

@petter Thanks for the post, learned a lot here. FYI, looks like your link to the BDK Env Variable plugin is no longer working. Here’s the corrected if you want to update: https://bubble.io/plugin/env-environment-variables-bdk-1540857498064x563539974936330200

“This can be used to share info, trigger workflows or whatever kinky stuff you’re into.”

^ Made me crack up. :joy: