Bubble.io Custom States and URL Parameters: Advanced State Management
Custom states, URL parameters, and the database serve different purposes in Bubble. Using the wrong one causes bugs that are hard to find. This guide maps every state management scenario to the correct solution.
Custom States vs. URL Parameters vs. Database — When to Use Each
State management is the practice of deciding where to store information that controls what the user sees. Bubble gives you three options: custom states (in-memory, reset on page refresh), URL parameters (persistent across refresh, shareable), and the database (permanent, server-side). Choosing the wrong one creates bugs that are surprisingly difficult to diagnose.
| Storage Type | Persists on Refresh? | Shareable URL? | Server-Side? | Use For |
|---|---|---|---|---|
| Custom State | No | No | No | UI toggle states, active tab, search input, modal open/closed, selected item highlight |
| URL Parameter | Yes | Yes | No | Current page in pagination, active filter, selected record ID for deep links |
| Database Field | Yes | Yes (via ID) | Yes | User preferences, saved filters, onboarding completion, anything that needs to survive session |
| Local Storage (JS) | Yes | No | No | Rarely needed in Bubble — use database fields instead |
The Most Valuable Custom State Patterns
Pattern 1: Tab Navigation
Tab “Overview” click: Set Page’s active_tab = “overview”
Tab “Members” click: Set Page’s active_tab = “members”
Tab “Billing” click: Set Page’s active_tab = “billing”
// Tab styling: underline/active class when state matches
Overview tab style “active” when: Page’s active_tab = “overview”
// Content visibility
Overview group visible when: Page’s active_tab = “overview”
Members group visible when: Page’s active_tab = “members”
Pattern 2: Selected Item in a List
// When user clicks a row in the project list RG:
Row click workflow: Set Page’s selected_project = Current Cell’s Project
// Detail panel shows selected project’s data
Detail panel visible when: Page’s selected_project is not empty
Detail title text: Page’s selected_project’s name
// Row highlight in RG cell
Row background when: Current Cell’s Project = Page’s selected_project
Pattern 3: URL Parameters for Deep Links
Navigate to Settings: /settings?tab=billing
// On page load: read URL param and set state
Page load workflow:
Only when: Get data from URL “tab” is not empty
Set Page’s active_tab = Get data from URL “tab”
// Now /settings?tab=billing opens directly on the Billing tab
// Shareable link — customer support can send users directly to billing
Pattern 4: Multi-Step Form State
Step 1 group visible when: form_step = 1
Step 2 group visible when: form_step = 2
// “Next” button advances step
Next button click:
Only when: required fields on current step are not empty
Set form_step = form_step + 1
// Progress indicator
Progress text: Step [form_step] of 4
Progress bar width: form_step / 4 * 100%
Ready to Build on Bubble?
Architecture, data model design, Stripe billing, and full SaaS builds — done right from day one.
