I’m developing a complex Educational Web Application on Bubble. We’ve managed to build a functional quiz engine (with custom scoring logic and smooth navigation).
Our central architecture relies on Hybrid Data Management:
Selection (Live Game): Choices are stored instantly in a Page-Level Custom State (user_choices). This ensures zero latency.
Archiving (Post-Validation): The Custom State is saved to the UserAnswer database table.
The Critical Persistence Problem
When the user leaves the quiz session (or clicks ‘Previous’) and returns to an unanswered question, the UI is blank. The stored data is not reflected because the visual elements only look at the now-empty Custom State.
When accessing a completed, archived session (Review Mode), the UI is also blank because the checkmarks rely on the Custom State, not the archived database entries.
The Technical Block
We need a robust method to “Rehydrate” the UI—restoring the correct checkmarks, validation status, and correction colors—by pulling the archived data back into the application state without slowing down the app or creating logic conflicts.
We are struggling with the most efficient strategy to:
Conditional Rehydration: Execute a search for the archived UserAnswer (DB) and load its content into the Custom State (user_choices) whenever a question slide is loaded/viewed.
Locking: Reliably disable all interaction workflows (clicking/toggling) when the app is in “Review Mode” (reading from the database).
Any proven methods for efficiently handling this Custom State / Database synchronization in a single-page carousel application would be greatly appreciated.
I use api objects and local storage for this. I have a paid plugin called Data Jedi that makes this a breeze with ability to have lists of objects and extra value (think quiz question number or form step), all in sync with on page and local storage due to event triggers to modify objects, write and read local storage.
Now in my forms and test apps I don’t even need a url parameter or path list to manage navigation. Users can go back and forward and I know what steps/questions already completed and which they are cute looking at. And if they leave site before completing, everything is in local storage and I show popup asking if they want to start again or pick up where they left off. Can also save to DB whenever I want to capture important data, like email, especially important on long forms.
Sure, here’s a stronger version while still keeping it short and human:
Yeah, this approach is the right one. Bubble won’t keep custom states alive once the user moves away, so the only reliable pattern is to rebuild the UI state from the database whenever a question loads. That way the quiz feels instant because you’re still using custom states for the actual interaction, but the data is always correct when someone comes back later or enters review mode.
The review-mode lock using a simple flag is also the cleanest way to avoid conflicts. Once that flag is active, you just stop all “choice update” workflows, and the UI becomes fully read-only. It keeps things predictable, especially in single-page apps where multiple workflows fire at the same time.
Most advanced quiz systems on Bubble basically use this same structure—fast custom states for live play, and a DB → state rehydration pass whenever the user returns to a question. It’s stable, scalable, and avoids those weird “blank UI” issues.
Quick question so I can tailor it properly: are your questions inside a repeating group or individual groups in a slider/carousel?
Maybe most as in majority, a way to quantify how many do it, BUT the MOST advanced quiz systems do not.
This costs search WU consumption on every single back and forward navigation, which will make any quiz app on bubble dead in water if it starts to scale. Data fetch and writes add up quickly on these types of features.
For your Custom State and Database sync issue, here’s a proven approach:
On page load workflow:
Search for UserAnswer where question = current question
If search result is not empty, set custom state user_choices to search result’s answer
Add conditional to only run this when returning to a previously answered question
For Review Mode locking:
Add a custom state “is_review_mode” (yes/no)
Then on every clickable element add a conditional: “When is_review_mode is yes, This element is not clickable”
Alternative approach:
Instead of managing two sources of truth (custom state + DB), consider using only URL parameters or DB with cached reads. Custom states can get messy when you need persistence.
For better performance on rehydration, structure your DB search to load all answers for the session upfront, then reference that list rather than searching per question.
Happy to discuss specific implementation if you share your editor link.
Instead of using custom states, use the data directly. Example: Change page type to “Quiz” or a Main group with this type. Then every reference to this you use “Parent group’Quiz”. Change privacy rules to use autobinding when you can, it auto saves the fields and it’s faster to implement.